gstreamer_core/gst/gsttaglist.c
changeset 16 8e837d1bf446
parent 0 0e761a78d257
child 30 7e817e7e631c
equal deleted inserted replaced
15:4b0c6ed43234 16:8e837d1bf446
    23  * SECTION:gsttaglist
    23  * SECTION:gsttaglist
    24  * @short_description: List of tags and values used to describe media metadata
    24  * @short_description: List of tags and values used to describe media metadata
    25  *
    25  *
    26  * List of tags and values used to describe media metadata.
    26  * List of tags and values used to describe media metadata.
    27  *
    27  *
    28  * Last reviewed on 2005-11-23 (0.9.5)
    28  * Strings must be in ASCII or UTF-8 encoding. No other encodings are allowed.
       
    29  *
       
    30  * Last reviewed on 2009-06-09 (0.10.23)
    29  */
    31  */
    30 
    32 
    31 #ifdef HAVE_CONFIG_H
    33 #ifdef HAVE_CONFIG_H
    32 #  include "config.h"
    34 #  include "config.h"
    33 #endif
    35 #endif
    36 #include "gst-i18n-lib.h"
    38 #include "gst-i18n-lib.h"
    37 #include "gsttaglist.h"
    39 #include "gsttaglist.h"
    38 #include "gstinfo.h"
    40 #include "gstinfo.h"
    39 #include "gstvalue.h"
    41 #include "gstvalue.h"
    40 #include "gstbuffer.h"
    42 #include "gstbuffer.h"
       
    43 #include "gstquark.h"
    41 
    44 
    42 #include <gobject/gvaluecollector.h>
    45 #include <gobject/gvaluecollector.h>
    43 #include <string.h>
    46 #include <string.h>
    44 
    47 
    45 #ifdef __SYMBIAN32__
    48 #ifdef __SYMBIAN32__
    62   GstTagMergeFunc merge_func;   /* functions to merge the values */
    65   GstTagMergeFunc merge_func;   /* functions to merge the values */
    63   GstTagFlag flag;              /* type of tag */
    66   GstTagFlag flag;              /* type of tag */
    64 }
    67 }
    65 GstTagInfo;
    68 GstTagInfo;
    66 
    69 
    67 #define TAGLIST "taglist"
       
    68 static GQuark gst_tag_list_quark;
       
    69 static GMutex *__tag_mutex;
    70 static GMutex *__tag_mutex;
       
    71 
    70 static GHashTable *__tags;
    72 static GHashTable *__tags;
    71 
    73 
    72 #define TAG_LOCK g_mutex_lock (__tag_mutex)
    74 #define TAG_LOCK g_mutex_lock (__tag_mutex)
    73 #define TAG_UNLOCK g_mutex_unlock (__tag_mutex)
    75 #define TAG_UNLOCK g_mutex_unlock (__tag_mutex)
    74 
    76 
    75 #ifdef __SYMBIAN32__
    77 #ifdef __SYMBIAN32__
    76 EXPORT_C
    78 EXPORT_C
    77 #endif
    79 #endif
       
    80 
    78 GType
    81 GType
    79 gst_tag_list_get_type (void)
    82 gst_tag_list_get_type (void)
    80 {
    83 {
    81   static GType _gst_tag_list_type = 0;
    84   static GType _gst_tag_list_type = 0;
    82 
    85 
    98 
   101 
    99 
   102 
   100 void
   103 void
   101 _gst_tag_initialize (void)
   104 _gst_tag_initialize (void)
   102 {
   105 {
   103   gst_tag_list_quark = g_quark_from_static_string (TAGLIST);
       
   104   __tag_mutex = g_mutex_new ();
   106   __tag_mutex = g_mutex_new ();
   105   __tags = g_hash_table_new (g_direct_hash, g_direct_equal);
   107   __tags = g_hash_table_new (g_direct_hash, g_direct_equal);
   106   gst_tag_register (GST_TAG_TITLE, GST_TAG_FLAG_META,
   108   gst_tag_register (GST_TAG_TITLE, GST_TAG_FLAG_META,
   107       G_TYPE_STRING,
   109       G_TYPE_STRING,
   108       _("title"), _("commonly used title"), gst_tag_merge_strings_with_comma);
   110       _("title"), _("commonly used title"), gst_tag_merge_strings_with_comma);
   160       _("count of discs inside collection this disc belongs to"),
   162       _("count of discs inside collection this disc belongs to"),
   161       gst_tag_merge_use_first);
   163       gst_tag_merge_use_first);
   162   gst_tag_register (GST_TAG_LOCATION, GST_TAG_FLAG_META,
   164   gst_tag_register (GST_TAG_LOCATION, GST_TAG_FLAG_META,
   163       G_TYPE_STRING,
   165       G_TYPE_STRING,
   164       _("location"),
   166       _("location"),
   165       _("original location of file as a URI"),
   167       _
       
   168       ("Origin of media as a URI (location, where the original of the file or stream is hosted)"),
   166       gst_tag_merge_strings_with_comma);
   169       gst_tag_merge_strings_with_comma);
   167   gst_tag_register (GST_TAG_DESCRIPTION, GST_TAG_FLAG_META,
   170   gst_tag_register (GST_TAG_HOMEPAGE, GST_TAG_FLAG_META,
   168       G_TYPE_STRING,
   171       G_TYPE_STRING,
   169       _("description"),
   172       _("homepage"),
   170       _("short text describing the content of the data"),
   173       _
       
   174       ("Homepage for this media (i.e. artist or movie homepage)"),
   171       gst_tag_merge_strings_with_comma);
   175       gst_tag_merge_strings_with_comma);
   172   gst_tag_register (GST_TAG_VERSION, GST_TAG_FLAG_META,
   176   gst_tag_register (GST_TAG_DESCRIPTION, GST_TAG_FLAG_META, G_TYPE_STRING,
   173       G_TYPE_STRING, _("version"), _("version of this data"), NULL);
   177       _("description"), _("short text describing the content of the data"),
   174   gst_tag_register (GST_TAG_ISRC, GST_TAG_FLAG_META,
   178       gst_tag_merge_strings_with_comma);
   175       G_TYPE_STRING,
   179   gst_tag_register (GST_TAG_VERSION, GST_TAG_FLAG_META, G_TYPE_STRING,
   176       _("ISRC"),
   180       _("version"), _("version of this data"), NULL);
       
   181   gst_tag_register (GST_TAG_ISRC, GST_TAG_FLAG_META, G_TYPE_STRING, _("ISRC"),
   177       _
   182       _
   178       ("International Standard Recording Code - see http://www.ifpi.org/isrc/"),
   183       ("International Standard Recording Code - see http://www.ifpi.org/isrc/"),
   179       NULL);
   184       NULL);
   180   gst_tag_register (GST_TAG_ORGANIZATION, GST_TAG_FLAG_META, G_TYPE_STRING, _("organization"), _("organization"),       /* FIXME */
   185   gst_tag_register (GST_TAG_ORGANIZATION, GST_TAG_FLAG_META, G_TYPE_STRING, _("organization"), _("organization"),       /* FIXME */
   181       gst_tag_merge_strings_with_comma);
   186       gst_tag_merge_strings_with_comma);
   212       G_TYPE_STRING,
   217       G_TYPE_STRING,
   213       _("video codec"), _("codec the video data is stored in"), NULL);
   218       _("video codec"), _("codec the video data is stored in"), NULL);
   214   gst_tag_register (GST_TAG_AUDIO_CODEC, GST_TAG_FLAG_ENCODED,
   219   gst_tag_register (GST_TAG_AUDIO_CODEC, GST_TAG_FLAG_ENCODED,
   215       G_TYPE_STRING,
   220       G_TYPE_STRING,
   216       _("audio codec"), _("codec the audio data is stored in"), NULL);
   221       _("audio codec"), _("codec the audio data is stored in"), NULL);
       
   222   gst_tag_register (GST_TAG_SUBTITLE_CODEC, GST_TAG_FLAG_ENCODED,
       
   223       G_TYPE_STRING,
       
   224       _("subtitle codec"), _("codec the subtitle data is stored in"), NULL);
       
   225   gst_tag_register (GST_TAG_CONTAINER_FORMAT, GST_TAG_FLAG_ENCODED,
       
   226       G_TYPE_STRING, _("container format"),
       
   227       _("container format the data is stored in"), NULL);
   217   gst_tag_register (GST_TAG_BITRATE, GST_TAG_FLAG_ENCODED,
   228   gst_tag_register (GST_TAG_BITRATE, GST_TAG_FLAG_ENCODED,
   218       G_TYPE_UINT, _("bitrate"), _("exact or average bitrate in bits/s"), NULL);
   229       G_TYPE_UINT, _("bitrate"), _("exact or average bitrate in bits/s"), NULL);
   219   gst_tag_register (GST_TAG_NOMINAL_BITRATE, GST_TAG_FLAG_ENCODED,
   230   gst_tag_register (GST_TAG_NOMINAL_BITRATE, GST_TAG_FLAG_ENCODED,
   220       G_TYPE_UINT, _("nominal bitrate"), _("nominal bitrate in bits/s"), NULL);
   231       G_TYPE_UINT, _("nominal bitrate"), _("nominal bitrate in bits/s"), NULL);
   221   gst_tag_register (GST_TAG_MINIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
   232   gst_tag_register (GST_TAG_MINIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
   247       _("language code for this stream, conforming to ISO-639-1"), NULL);
   258       _("language code for this stream, conforming to ISO-639-1"), NULL);
   248   gst_tag_register (GST_TAG_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
   259   gst_tag_register (GST_TAG_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
   249       _("image"), _("image related to this stream"), gst_tag_merge_use_first);
   260       _("image"), _("image related to this stream"), gst_tag_merge_use_first);
   250   gst_tag_register (GST_TAG_PREVIEW_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
   261   gst_tag_register (GST_TAG_PREVIEW_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
   251       _("preview image"), _("preview image related to this stream"), NULL);
   262       _("preview image"), _("preview image related to this stream"), NULL);
       
   263   gst_tag_register (GST_TAG_ATTACHMENT, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
       
   264       _("attachment"), _("file attached to this stream"),
       
   265       gst_tag_merge_use_first);
   252   gst_tag_register (GST_TAG_BEATS_PER_MINUTE, GST_TAG_FLAG_META, G_TYPE_DOUBLE,
   266   gst_tag_register (GST_TAG_BEATS_PER_MINUTE, GST_TAG_FLAG_META, G_TYPE_DOUBLE,
   253       _("beats per minute"), _("number of beats per minute in audio"), NULL);
   267       _("beats per minute"), _("number of beats per minute in audio"), NULL);
   254 
   268   gst_tag_register (GST_TAG_KEYWORDS, GST_TAG_FLAG_META, G_TYPE_STRING,
       
   269       _("keywords"), _("comma separated keywords describing the content"),
       
   270       gst_tag_merge_strings_with_comma);
       
   271   gst_tag_register (GST_TAG_GEO_LOCATION_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
       
   272       _("geo location name"),
       
   273       _
       
   274       ("human readable descriptive location of where the media has been recorded or produced"),
       
   275       NULL);
       
   276   gst_tag_register (GST_TAG_GEO_LOCATION_LATITUDE, GST_TAG_FLAG_META,
       
   277       G_TYPE_DOUBLE, _("geo location latitude"),
       
   278       _
       
   279       ("geo latitude location of where the media has been recorded or produced in degrees according to WGS84 (zero at the equator, negative values for southern latitudes)"),
       
   280       NULL);
       
   281   gst_tag_register (GST_TAG_GEO_LOCATION_LONGITUDE, GST_TAG_FLAG_META,
       
   282       G_TYPE_DOUBLE, _("geo location longitude"),
       
   283       _
       
   284       ("geo longitude location of where the media has been recorded or produced in degrees according to WGS84 (zero at the prime meridian in Greenwich/UK,  negative values for western longitudes)"),
       
   285       NULL);
       
   286   gst_tag_register (GST_TAG_GEO_LOCATION_ELEVATION, GST_TAG_FLAG_META,
       
   287       G_TYPE_DOUBLE, _("geo location elevation"),
       
   288       _
       
   289       ("geo elevation of where the media has been recorded or produced in meters according to WGS84 (zero is average sea level)"),
       
   290       NULL);
   255 }
   291 }
   256 
   292 
   257 /**
   293 /**
   258  * gst_tag_merge_use_first:
   294  * gst_tag_merge_use_first:
   259  * @dest: uninitialized GValue to store result in
   295  * @dest: uninitialized GValue to store result in
   290 
   326 
   291 void
   327 void
   292 gst_tag_merge_strings_with_comma (GValue * dest, const GValue * src)
   328 gst_tag_merge_strings_with_comma (GValue * dest, const GValue * src)
   293 {
   329 {
   294   GString *str;
   330   GString *str;
       
   331 
   295   gint i, count;
   332   gint i, count;
   296 
   333 
   297   count = gst_value_list_get_size (src);
   334   count = gst_value_list_get_size (src);
   298   str = g_string_new (g_value_get_string (gst_value_list_get_value (src, 0)));
   335   str = g_string_new (g_value_get_string (gst_value_list_get_value (src, 0)));
   299   for (i = 1; i < count; i++) {
   336   for (i = 1; i < count; i++) {
   303         g_string_append (str, g_value_get_string (gst_value_list_get_value (src,
   340         g_string_append (str, g_value_get_string (gst_value_list_get_value (src,
   304                 1)));
   341                 1)));
   305   }
   342   }
   306 
   343 
   307   g_value_init (dest, G_TYPE_STRING);
   344   g_value_init (dest, G_TYPE_STRING);
   308   g_value_set_string_take_ownership (dest, str->str);
   345   g_value_take_string (dest, str->str);
   309   g_string_free (str, FALSE);
   346   g_string_free (str, FALSE);
   310 }
   347 }
       
   348 
   311 static GstTagInfo *
   349 static GstTagInfo *
   312 gst_tag_lookup (GQuark entry)
   350 gst_tag_lookup (GQuark entry)
   313 {
   351 {
   314   GstTagInfo *ret;
   352   GstTagInfo *ret;
   315 
   353 
   358 void
   396 void
   359 gst_tag_register (const gchar * name, GstTagFlag flag, GType type,
   397 gst_tag_register (const gchar * name, GstTagFlag flag, GType type,
   360     const gchar * nick, const gchar * blurb, GstTagMergeFunc func)
   398     const gchar * nick, const gchar * blurb, GstTagMergeFunc func)
   361 {
   399 {
   362   GQuark key;
   400   GQuark key;
       
   401 
   363   GstTagInfo *info;
   402   GstTagInfo *info;
   364 
   403 
   365   g_return_if_fail (name != NULL);
   404   g_return_if_fail (name != NULL);
   366   g_return_if_fail (nick != NULL);
   405   g_return_if_fail (nick != NULL);
   367   g_return_if_fail (blurb != NULL);
   406   g_return_if_fail (blurb != NULL);
   542 #endif
   581 #endif
   543 
   582 
   544 GstTagList *
   583 GstTagList *
   545 gst_tag_list_new (void)
   584 gst_tag_list_new (void)
   546 {
   585 {
   547   return GST_TAG_LIST (gst_structure_new (TAGLIST, NULL));
   586   return GST_TAG_LIST (gst_structure_id_empty_new (GST_QUARK (TAGLIST)));
       
   587 }
       
   588 
       
   589 /**
       
   590  * gst_tag_list_new_full:
       
   591  * @tag: tag
       
   592  * @...: NULL-terminated list of values to set
       
   593  *
       
   594  * Creates a new taglist and appends the values for the given tags. It expects
       
   595  * tag-value pairs like gst_tag_list_add(), and a NULL terminator after the
       
   596  * last pair. The type of the values is implicit and is documented in the API
       
   597  * reference, but can also be queried at runtime with gst_tag_get_type(). It
       
   598  * is an error to pass a value of a type not matching the tag type into this
       
   599  * function. The tag list will make copies of any arguments passed
       
   600  * (e.g. strings, buffers).
       
   601  *
       
   602  * Returns: a new #GstTagList. Free with gst_tag_list_free() when no longer
       
   603  *     needed.
       
   604  *
       
   605  * Since: 0.10.24
       
   606  */
       
   607 /* FIXME 0.11: rename gst_tag_list_new_full to _new and _new to _new_empty */
       
   608 #ifdef __SYMBIAN32__
       
   609 EXPORT_C
       
   610 #endif
       
   611 
       
   612 GstTagList *
       
   613 gst_tag_list_new_full (const gchar * tag, ...)
       
   614 {
       
   615   GstTagList *list;
       
   616   va_list args;
       
   617 
       
   618   g_return_val_if_fail (tag != NULL, NULL);
       
   619 
       
   620   list = gst_tag_list_new ();
       
   621   va_start (args, tag);
       
   622   gst_tag_list_add_valist (list, GST_TAG_MERGE_APPEND, tag, args);
       
   623   va_end (args);
       
   624 
       
   625   return list;
       
   626 }
       
   627 
       
   628 /**
       
   629  * gst_tag_list_new_full_valist:
       
   630  * @var_args: tag / value pairs to set
       
   631  *
       
   632  * Just like gst_tag_list_new_full(), only that it takes a va_list argument.
       
   633  * Useful mostly for language bindings.
       
   634  *
       
   635  * Returns: a new #GstTagList. Free with gst_tag_list_free() when no longer
       
   636  *     needed.
       
   637  *
       
   638  * Since: 0.10.24
       
   639  */
       
   640 #ifdef __SYMBIAN32__
       
   641 EXPORT_C
       
   642 #endif
       
   643 
       
   644 GstTagList *
       
   645 gst_tag_list_new_full_valist (va_list var_args)
       
   646 {
       
   647   GstTagList *list;
       
   648   const gchar *tag;
       
   649 
       
   650   list = gst_tag_list_new ();
       
   651 
       
   652   tag = va_arg (var_args, gchar *);
       
   653   gst_tag_list_add_valist (list, GST_TAG_MERGE_APPEND, tag, var_args);
       
   654 
       
   655   return list;
   548 }
   656 }
   549 
   657 
   550 /**
   658 /**
   551  * gst_tag_list_is_empty:
   659  * gst_tag_list_is_empty:
   552  * @list: A #GstTagList.
   660  * @list: A #GstTagList.
   587 {
   695 {
   588   GstStructure *s = (GstStructure *) p;
   696   GstStructure *s = (GstStructure *) p;
   589 
   697 
   590   g_return_val_if_fail (p != NULL, FALSE);
   698   g_return_val_if_fail (p != NULL, FALSE);
   591 
   699 
   592   return (GST_IS_STRUCTURE (s) && s->name == gst_tag_list_quark);
   700   return (GST_IS_STRUCTURE (s) && s->name == GST_QUARK (TAGLIST));
   593 }
   701 }
       
   702 
   594 typedef struct
   703 typedef struct
   595 {
   704 {
   596   GstStructure *list;
   705   GstStructure *list;
   597   GstTagMergeMode mode;
   706   GstTagMergeMode mode;
   598 }
   707 }
   599 GstTagCopyData;
   708 GstTagCopyData;
       
   709 
   600 static void
   710 static void
   601 gst_tag_list_add_value_internal (GstStructure * list, GstTagMergeMode mode,
   711 gst_tag_list_add_value_internal (GstStructure * list, GstTagMergeMode mode,
   602     GQuark tag, const GValue * value)
   712     GQuark tag, const GValue * value)
   603 {
   713 {
   604   GstTagInfo *info = gst_tag_lookup (tag);
   714   GstTagInfo *info = gst_tag_lookup (tag);
       
   715 
   605   const GValue *value2;
   716   const GValue *value2;
   606 
   717 
   607   g_assert (info != NULL);
   718   g_assert (info != NULL);
   608 
   719 
   609   if (info->merge_func
   720   if (info->merge_func
   650         g_assert_not_reached ();
   761         g_assert_not_reached ();
   651         break;
   762         break;
   652     }
   763     }
   653   }
   764   }
   654 }
   765 }
       
   766 
   655 static gboolean
   767 static gboolean
   656 gst_tag_list_copy_foreach (GQuark tag, const GValue * value, gpointer user_data)
   768 gst_tag_list_copy_foreach (GQuark tag, const GValue * value, gpointer user_data)
   657 {
   769 {
   658   GstTagCopyData *copy = (GstTagCopyData *) user_data;
   770   GstTagCopyData *copy = (GstTagCopyData *) user_data;
   659 
   771 
   666  * gst_tag_list_insert:
   778  * gst_tag_list_insert:
   667  * @into: list to merge into
   779  * @into: list to merge into
   668  * @from: list to merge from
   780  * @from: list to merge from
   669  * @mode: the mode to use
   781  * @mode: the mode to use
   670  *
   782  *
   671  * Inserts the tags of the second list into the first list using the given mode.
   783  * Inserts the tags of the @from list into the first list using the given mode.
   672  */
   784  */
   673 #ifdef __SYMBIAN32__
   785 #ifdef __SYMBIAN32__
   674 EXPORT_C
   786 EXPORT_C
   675 #endif
   787 #endif
   676 
   788 
   730 
   842 
   731 GstTagList *
   843 GstTagList *
   732 gst_tag_list_merge (const GstTagList * list1, const GstTagList * list2,
   844 gst_tag_list_merge (const GstTagList * list1, const GstTagList * list2,
   733     GstTagMergeMode mode)
   845     GstTagMergeMode mode)
   734 {
   846 {
       
   847   GstTagList *list1_cp;
       
   848   const GstTagList *list2_cp;
       
   849 
   735   g_return_val_if_fail (list1 == NULL || GST_IS_TAG_LIST (list1), NULL);
   850   g_return_val_if_fail (list1 == NULL || GST_IS_TAG_LIST (list1), NULL);
   736   g_return_val_if_fail (list2 == NULL || GST_IS_TAG_LIST (list2), NULL);
   851   g_return_val_if_fail (list2 == NULL || GST_IS_TAG_LIST (list2), NULL);
   737   g_return_val_if_fail (GST_TAG_MODE_IS_VALID (mode), NULL);
   852   g_return_val_if_fail (GST_TAG_MODE_IS_VALID (mode), NULL);
   738 
   853 
       
   854   /* nothing to merge */
   739   if (!list1 && !list2) {
   855   if (!list1 && !list2) {
   740     return NULL;
   856     return NULL;
   741   } else if (!list1) {
       
   742     return gst_tag_list_copy (list2);
       
   743   } else if (!list2) {
       
   744     return gst_tag_list_copy (list1);
       
   745   } else {
       
   746     GstTagList *ret;
       
   747 
       
   748     ret = gst_tag_list_copy (list1);
       
   749     gst_tag_list_insert (ret, list2, mode);
       
   750     return ret;
       
   751   }
   857   }
       
   858 
       
   859   /* create empty list, we need to do this to correctly handling merge modes */
       
   860   list1_cp = (list1) ? gst_tag_list_copy (list1) : gst_tag_list_new ();
       
   861   list2_cp = (list2) ? list2 : gst_tag_list_new ();
       
   862 
       
   863   gst_tag_list_insert (list1_cp, list2_cp, mode);
       
   864 
       
   865   if (!list2)
       
   866     gst_tag_list_free ((GstTagList *) list2_cp);
       
   867 
       
   868   return list1_cp;
   752 }
   869 }
   753 
   870 
   754 /**
   871 /**
   755  * gst_tag_list_free:
   872  * gst_tag_list_free:
   756  * @list: the list to free
   873  * @list: the list to free
   875   gchar *error = NULL;
   992   gchar *error = NULL;
   876 
   993 
   877   g_return_if_fail (GST_IS_TAG_LIST (list));
   994   g_return_if_fail (GST_IS_TAG_LIST (list));
   878   g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
   995   g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
   879   g_return_if_fail (tag != NULL);
   996   g_return_if_fail (tag != NULL);
       
   997 
       
   998   if (mode == GST_TAG_MERGE_REPLACE_ALL) {
       
   999     gst_structure_remove_all_fields (list);
       
  1000   }
   880 
  1001 
   881   while (tag != NULL) {
  1002   while (tag != NULL) {
   882     GValue value = { 0, };
  1003     GValue value = { 0, };
   883 
  1004 
   884     quark = g_quark_from_string (tag);
  1005     quark = g_quark_from_string (tag);
   917 
  1038 
   918 void
  1039 void
   919 gst_tag_list_add_valist_values (GstTagList * list, GstTagMergeMode mode,
  1040 gst_tag_list_add_valist_values (GstTagList * list, GstTagMergeMode mode,
   920     const gchar * tag, va_list var_args)
  1041     const gchar * tag, va_list var_args)
   921 {
  1042 {
   922   GstTagInfo *info;
       
   923   GQuark quark;
  1043   GQuark quark;
   924 
  1044 
   925   g_return_if_fail (GST_IS_TAG_LIST (list));
  1045   g_return_if_fail (GST_IS_TAG_LIST (list));
   926   g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
  1046   g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
   927   g_return_if_fail (tag != NULL);
  1047   g_return_if_fail (tag != NULL);
   928 
  1048 
       
  1049   if (mode == GST_TAG_MERGE_REPLACE_ALL) {
       
  1050     gst_structure_remove_all_fields (list);
       
  1051   }
       
  1052 
   929   while (tag != NULL) {
  1053   while (tag != NULL) {
   930     quark = g_quark_from_string (tag);
  1054     quark = g_quark_from_string (tag);
   931     info = gst_tag_lookup (quark);
  1055     g_return_if_fail (gst_tag_lookup (quark) != NULL);
   932     g_return_if_fail (info != NULL);
       
   933     gst_tag_list_add_value_internal (list, mode, quark, va_arg (var_args,
  1056     gst_tag_list_add_value_internal (list, mode, quark, va_arg (var_args,
   934             GValue *));
  1057             GValue *));
   935     tag = va_arg (var_args, gchar *);
  1058     tag = va_arg (var_args, gchar *);
   936   }
  1059   }
   937 }
  1060 }
   938 
  1061 
   939 /**
  1062 /**
       
  1063  * gst_tag_list_add_value:
       
  1064  * @list: list to set tags in
       
  1065  * @mode: the mode to use
       
  1066  * @tag: tag
       
  1067  * @value: GValue for this tag
       
  1068  *
       
  1069  * Sets the GValue for a given tag using the specified mode.
       
  1070  *
       
  1071  * Since: 0.10.24
       
  1072  */
       
  1073 #ifdef __SYMBIAN32__
       
  1074 EXPORT_C
       
  1075 #endif
       
  1076 
       
  1077 void
       
  1078 gst_tag_list_add_value (GstTagList * list, GstTagMergeMode mode,
       
  1079     const gchar * tag, const GValue * value)
       
  1080 {
       
  1081   g_return_if_fail (GST_IS_TAG_LIST (list));
       
  1082   g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
       
  1083   g_return_if_fail (tag != NULL);
       
  1084 
       
  1085   gst_tag_list_add_value_internal (list, mode, g_quark_from_string (tag),
       
  1086       value);
       
  1087 }
       
  1088 
       
  1089 /**
   940  * gst_tag_list_remove_tag:
  1090  * gst_tag_list_remove_tag:
   941  * @list: list to remove tag from
  1091  * @list: list to remove tag from
   942  * @tag: tag to remove
  1092  * @tag: tag to remove
   943  *
  1093  *
   944  * Removes the given tag from the taglist.
  1094  * Removes the given tag from the taglist.
   953   g_return_if_fail (GST_IS_TAG_LIST (list));
  1103   g_return_if_fail (GST_IS_TAG_LIST (list));
   954   g_return_if_fail (tag != NULL);
  1104   g_return_if_fail (tag != NULL);
   955 
  1105 
   956   gst_structure_remove_field ((GstStructure *) list, tag);
  1106   gst_structure_remove_field ((GstStructure *) list, tag);
   957 }
  1107 }
       
  1108 
   958 typedef struct
  1109 typedef struct
   959 {
  1110 {
   960   GstTagForeachFunc func;
  1111   GstTagForeachFunc func;
   961   const GstTagList *tag_list;
  1112   const GstTagList *tag_list;
   962   gpointer data;
  1113   gpointer data;
   963 }
  1114 }
   964 TagForeachData;
  1115 TagForeachData;
       
  1116 
   965 static int
  1117 static int
   966 structure_foreach_wrapper (GQuark field_id, const GValue * value,
  1118 structure_foreach_wrapper (GQuark field_id, const GValue * value,
   967     gpointer user_data)
  1119     gpointer user_data)
   968 {
  1120 {
   969   TagForeachData *data = (TagForeachData *) user_data;
  1121   TagForeachData *data = (TagForeachData *) user_data;
  1075     return FALSE;
  1227     return FALSE;
  1076 
  1228 
  1077   if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
  1229   if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
  1078     GstTagInfo *info = gst_tag_lookup (g_quark_from_string (tag));
  1230     GstTagInfo *info = gst_tag_lookup (g_quark_from_string (tag));
  1079 
  1231 
       
  1232     if (!info)
       
  1233       return FALSE;
       
  1234 
  1080     /* must be there or lists aren't allowed */
  1235     /* must be there or lists aren't allowed */
  1081     g_assert (info->merge_func);
  1236     g_assert (info->merge_func);
  1082     info->merge_func (dest, src);
  1237     info->merge_func (dest, src);
  1083   } else {
  1238   } else {
  1084     g_value_init (dest, G_VALUE_TYPE (src));
  1239     g_value_init (dest, G_VALUE_TYPE (src));
  1096  * (unless someone can actually think of real use cases where the merge
  1251  * (unless someone can actually think of real use cases where the merge
  1097  * function is not 'use first' for non-strings and merge for strings) */
  1252  * function is not 'use first' for non-strings and merge for strings) */
  1098 
  1253 
  1099 /***** evil macros to get all the gst_tag_list_get_*() functions right *****/
  1254 /***** evil macros to get all the gst_tag_list_get_*() functions right *****/
  1100 
  1255 
  1101 #define TAG_MERGE_FUNCS(name,type)                                      \
  1256 #define TAG_MERGE_FUNCS(name,type,ret)                                  \
  1102 gboolean                                                                \
  1257 gboolean                                                                \
  1103 __declspec(dllexport)	gst_tag_list_get_ ## name (const GstTagList *list, const gchar *tag,    \
  1258 __declspec(dllexport)	gst_tag_list_get_ ## name (const GstTagList *list, const gchar *tag,    \
  1104                            type *value)                                 \
  1259                            type *value)                                 \
  1105 {                                                                       \
  1260 {                                                                       \
  1106   GValue v = { 0, };                                                    \
  1261   GValue v = { 0, };                                                    \
  1111                                                                         \
  1266                                                                         \
  1112   if (!gst_tag_list_copy_value (&v, list, tag))                         \
  1267   if (!gst_tag_list_copy_value (&v, list, tag))                         \
  1113       return FALSE;                                                     \
  1268       return FALSE;                                                     \
  1114   *value = COPY_FUNC (g_value_get_ ## name (&v));                       \
  1269   *value = COPY_FUNC (g_value_get_ ## name (&v));                       \
  1115   g_value_unset (&v);                                                   \
  1270   g_value_unset (&v);                                                   \
  1116   return TRUE;                                                          \
  1271   return ret;                                                           \
  1117 }                                                                       \
  1272 }                                                                       \
  1118                                                                         \
  1273                                                                         \
  1119 __declspec(dllexport)	gboolean                                                                \
  1274 __declspec(dllexport)	gboolean                                                                \
  1120 gst_tag_list_get_ ## name ## _index (const GstTagList *list,            \
  1275 gst_tag_list_get_ ## name ## _index (const GstTagList *list,            \
  1121                                      const gchar *tag,                  \
  1276                                      const gchar *tag,                  \
  1128   g_return_val_if_fail (value != NULL, FALSE);                          \
  1283   g_return_val_if_fail (value != NULL, FALSE);                          \
  1129                                                                         \
  1284                                                                         \
  1130   if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)    \
  1285   if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)    \
  1131       return FALSE;                                                     \
  1286       return FALSE;                                                     \
  1132   *value = COPY_FUNC (g_value_get_ ## name (v));                        \
  1287   *value = COPY_FUNC (g_value_get_ ## name (v));                        \
  1133   return TRUE;                                                          \
  1288   return ret;                                                           \
  1134 }
  1289 }
  1135 
  1290 
  1136 /* FIXME 0.11: maybe get rid of _get_char*(), _get_uchar*(), _get_long*(),
  1291 /* FIXME 0.11: maybe get rid of _get_char*(), _get_uchar*(), _get_long*(),
  1137  * _get_ulong*() and _get_pointer*()? - they are not really useful/common
  1292  * _get_ulong*() and _get_pointer*()? - they are not really useful/common
  1138  * enough to warrant convenience accessor functions */
  1293  * enough to warrant convenience accessor functions */
  1161  * list.
  1316  * list.
  1162  *
  1317  *
  1163  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1318  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1164  *              given list.
  1319  *              given list.
  1165  */
  1320  */
  1166 TAG_MERGE_FUNCS (char, gchar)
  1321 TAG_MERGE_FUNCS (char, gchar, TRUE)
  1167 /**
  1322 /**
  1168  * gst_tag_list_get_uchar:
  1323  * gst_tag_list_get_uchar:
  1169  * @list: a #GstTagList to get the tag from
  1324  * @list: a #GstTagList to get the tag from
  1170  * @tag: tag to read out
  1325  * @tag: tag to read out
  1171  * @value: location for the result
  1326  * @value: location for the result
  1187  * list.
  1342  * list.
  1188  *
  1343  *
  1189  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1344  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1190  *              given list.
  1345  *              given list.
  1191  */
  1346  */
  1192 TAG_MERGE_FUNCS (uchar, guchar)
  1347 TAG_MERGE_FUNCS (uchar, guchar, TRUE)
  1193 /**
  1348 /**
  1194  * gst_tag_list_get_boolean:
  1349  * gst_tag_list_get_boolean:
  1195  * @list: a #GstTagList to get the tag from
  1350  * @list: a #GstTagList to get the tag from
  1196  * @tag: tag to read out
  1351  * @tag: tag to read out
  1197  * @value: location for the result
  1352  * @value: location for the result
  1213  * list.
  1368  * list.
  1214  *
  1369  *
  1215  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1370  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1216  *              given list.
  1371  *              given list.
  1217  */
  1372  */
  1218 TAG_MERGE_FUNCS (boolean, gboolean)
  1373 TAG_MERGE_FUNCS (boolean, gboolean, TRUE)
  1219 /**
  1374 /**
  1220  * gst_tag_list_get_int:
  1375  * gst_tag_list_get_int:
  1221  * @list: a #GstTagList to get the tag from
  1376  * @list: a #GstTagList to get the tag from
  1222  * @tag: tag to read out
  1377  * @tag: tag to read out
  1223  * @value: location for the result
  1378  * @value: location for the result
  1239  * list.
  1394  * list.
  1240  *
  1395  *
  1241  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1396  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1242  *              given list.
  1397  *              given list.
  1243  */
  1398  */
  1244 TAG_MERGE_FUNCS (int, gint)
  1399 TAG_MERGE_FUNCS (int, gint, TRUE)
  1245 /**
  1400 /**
  1246  * gst_tag_list_get_uint:
  1401  * gst_tag_list_get_uint:
  1247  * @list: a #GstTagList to get the tag from
  1402  * @list: a #GstTagList to get the tag from
  1248  * @tag: tag to read out
  1403  * @tag: tag to read out
  1249  * @value: location for the result
  1404  * @value: location for the result
  1265  * list.
  1420  * list.
  1266  *
  1421  *
  1267  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1422  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1268  *              given list.
  1423  *              given list.
  1269  */
  1424  */
  1270 TAG_MERGE_FUNCS (uint, guint)
  1425 TAG_MERGE_FUNCS (uint, guint, TRUE)
  1271 /**
  1426 /**
  1272  * gst_tag_list_get_long:
  1427  * gst_tag_list_get_long:
  1273  * @list: a #GstTagList to get the tag from
  1428  * @list: a #GstTagList to get the tag from
  1274  * @tag: tag to read out
  1429  * @tag: tag to read out
  1275  * @value: location for the result
  1430  * @value: location for the result
  1291  * list.
  1446  * list.
  1292  *
  1447  *
  1293  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1448  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1294  *              given list.
  1449  *              given list.
  1295  */
  1450  */
  1296 TAG_MERGE_FUNCS (long, glong)
  1451 TAG_MERGE_FUNCS (long, glong, TRUE)
  1297 /**
  1452 /**
  1298  * gst_tag_list_get_ulong:
  1453  * gst_tag_list_get_ulong:
  1299  * @list: a #GstTagList to get the tag from
  1454  * @list: a #GstTagList to get the tag from
  1300  * @tag: tag to read out
  1455  * @tag: tag to read out
  1301  * @value: location for the result
  1456  * @value: location for the result
  1317  * list.
  1472  * list.
  1318  *
  1473  *
  1319  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1474  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1320  *              given list.
  1475  *              given list.
  1321  */
  1476  */
  1322 TAG_MERGE_FUNCS (ulong, gulong)
  1477 TAG_MERGE_FUNCS (ulong, gulong, TRUE)
  1323 /**
  1478 /**
  1324  * gst_tag_list_get_int64:
  1479  * gst_tag_list_get_int64:
  1325  * @list: a #GstTagList to get the tag from
  1480  * @list: a #GstTagList to get the tag from
  1326  * @tag: tag to read out
  1481  * @tag: tag to read out
  1327  * @value: location for the result
  1482  * @value: location for the result
  1343  * list.
  1498  * list.
  1344  *
  1499  *
  1345  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1500  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1346  *              given list.
  1501  *              given list.
  1347  */
  1502  */
  1348 TAG_MERGE_FUNCS (int64, gint64)
  1503 TAG_MERGE_FUNCS (int64, gint64, TRUE)
  1349 /**
  1504 /**
  1350  * gst_tag_list_get_uint64:
  1505  * gst_tag_list_get_uint64:
  1351  * @list: a #GstTagList to get the tag from
  1506  * @list: a #GstTagList to get the tag from
  1352  * @tag: tag to read out
  1507  * @tag: tag to read out
  1353  * @value: location for the result
  1508  * @value: location for the result
  1369  * list.
  1524  * list.
  1370  *
  1525  *
  1371  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1526  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1372  *              given list.
  1527  *              given list.
  1373  */
  1528  */
  1374 TAG_MERGE_FUNCS (uint64, guint64)
  1529 TAG_MERGE_FUNCS (uint64, guint64, TRUE)
  1375 /**
  1530 /**
  1376  * gst_tag_list_get_float:
  1531  * gst_tag_list_get_float:
  1377  * @list: a #GstTagList to get the tag from
  1532  * @list: a #GstTagList to get the tag from
  1378  * @tag: tag to read out
  1533  * @tag: tag to read out
  1379  * @value: location for the result
  1534  * @value: location for the result
  1395  * list.
  1550  * list.
  1396  *
  1551  *
  1397  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1552  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1398  *              given list.
  1553  *              given list.
  1399  */
  1554  */
  1400 TAG_MERGE_FUNCS (float, gfloat)
  1555 TAG_MERGE_FUNCS (float, gfloat, TRUE)
  1401 /**
  1556 /**
  1402  * gst_tag_list_get_double:
  1557  * gst_tag_list_get_double:
  1403  * @list: a #GstTagList to get the tag from
  1558  * @list: a #GstTagList to get the tag from
  1404  * @tag: tag to read out
  1559  * @tag: tag to read out
  1405  * @value: location for the result
  1560  * @value: location for the result
  1421  * list.
  1576  * list.
  1422  *
  1577  *
  1423  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1578  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1424  *              given list.
  1579  *              given list.
  1425  */
  1580  */
  1426 TAG_MERGE_FUNCS (double, gdouble)
  1581 TAG_MERGE_FUNCS (double, gdouble, TRUE)
  1427 /**
  1582 /**
  1428  * gst_tag_list_get_pointer:
  1583  * gst_tag_list_get_pointer:
  1429  * @list: a #GstTagList to get the tag from
  1584  * @list: a #GstTagList to get the tag from
  1430  * @tag: tag to read out
  1585  * @tag: tag to read out
  1431  * @value: location for the result
  1586  * @value: location for the result
  1447  * list.
  1602  * list.
  1448  *
  1603  *
  1449  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1604  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1450  *              given list.
  1605  *              given list.
  1451  */
  1606  */
  1452 TAG_MERGE_FUNCS (pointer, gpointer)
  1607 TAG_MERGE_FUNCS (pointer, gpointer, (*value != NULL))
  1453 #undef COPY_FUNC
  1608 #undef COPY_FUNC
  1454 #define COPY_FUNC g_strdup
  1609 #define COPY_FUNC g_strdup
  1455 /**
  1610 /**
  1456  * gst_tag_list_get_string:
  1611  * gst_tag_list_get_string:
  1457  * @list: a #GstTagList to get the tag from
  1612  * @list: a #GstTagList to get the tag from
  1463  *
  1618  *
  1464  * Use gst_tag_list_get_string_index (list, tag, 0, value) if you want
  1619  * Use gst_tag_list_get_string_index (list, tag, 0, value) if you want
  1465  * to retrieve the first string associated with this tag unmodified.
  1620  * to retrieve the first string associated with this tag unmodified.
  1466  *
  1621  *
  1467  * The resulting string in @value will be in UTF-8 encoding and should be
  1622  * The resulting string in @value will be in UTF-8 encoding and should be
  1468  * freed by the caller using g_free when no longer needed.
  1623  * freed by the caller using g_free when no longer needed. Since 0.10.24 the
       
  1624  * returned string is also guaranteed to be non-NULL and non-empty.
  1469  *
  1625  *
  1470  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1626  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1471  *              given list.
  1627  *              given list.
  1472  */
  1628  */
  1473 /**
  1629 /**
  1479  *
  1635  *
  1480  * Gets the value that is at the given index for the given tag in the given
  1636  * Gets the value that is at the given index for the given tag in the given
  1481  * list.
  1637  * list.
  1482  *
  1638  *
  1483  * The resulting string in @value will be in UTF-8 encoding and should be
  1639  * The resulting string in @value will be in UTF-8 encoding and should be
  1484  * freed by the caller using g_free when no longer needed.
  1640  * freed by the caller using g_free when no longer needed. Since 0.10.24 the
  1485  *
  1641  * returned string is also guaranteed to be non-NULL and non-empty.
  1486  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1642  *
  1487  *              given list.
  1643  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1488  */
  1644  *              given list.
  1489 TAG_MERGE_FUNCS (string, gchar *)
  1645  */
       
  1646 TAG_MERGE_FUNCS (string, gchar *, (*value != NULL && **value != '\0'))
  1490 
  1647 
  1491 /**
  1648 /**
  1492  * gst_tag_list_get_date:
  1649  * gst_tag_list_get_date:
  1493  * @list: a #GstTagList to get the tag from
  1650  * @list: a #GstTagList to get the tag from
  1494  * @tag: tag to read out
  1651  * @tag: tag to read out
  1495  * @value: location for the result
  1652  * @value: address of a GDate pointer variable to store the result into
  1496  *
  1653  *
  1497  * Copies the contents for the given tag into the value, merging multiple values
  1654  * Copies the first date for the given tag in the taglist into the variable
  1498  * into one if multiple values are associated with the tag.
  1655  * pointed to by @value. Free the date with g_date_free() when it is no longer
  1499  *
  1656  * needed.
  1500  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1657  *
       
  1658  * Returns: TRUE, if a date was copied, FALSE if the tag didn't exist in the
  1501  *              given list or if it was #NULL.
  1659  *              given list or if it was #NULL.
  1502  */
  1660  */
  1503 #ifdef __SYMBIAN32__
  1661 #ifdef __SYMBIAN32__
  1504 EXPORT_C
  1662 EXPORT_C
  1505 #endif
  1663 #endif
  1526  * @list: a #GstTagList to get the tag from
  1684  * @list: a #GstTagList to get the tag from
  1527  * @tag: tag to read out
  1685  * @tag: tag to read out
  1528  * @index: number of entry to read out
  1686  * @index: number of entry to read out
  1529  * @value: location for the result
  1687  * @value: location for the result
  1530  *
  1688  *
  1531  * Gets the value that is at the given index for the given tag in the given
  1689  * Gets the date that is at the given index for the given tag in the given
  1532  * list.
  1690  * list and copies it into the variable pointed to by @value. Free the date
       
  1691  * with g_date_free() when it is no longer needed.
  1533  *
  1692  *
  1534  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1693  * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
  1535  *              given list or if it was #NULL.
  1694  *              given list or if it was #NULL.
  1536  */
  1695  */
  1537 #ifdef __SYMBIAN32__
  1696 #ifdef __SYMBIAN32__
  1551   if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
  1710   if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
  1552     return FALSE;
  1711     return FALSE;
  1553   *value = (GDate *) g_value_dup_boxed (v);
  1712   *value = (GDate *) g_value_dup_boxed (v);
  1554   return (*value != NULL);
  1713   return (*value != NULL);
  1555 }
  1714 }
       
  1715 
       
  1716 /**
       
  1717  * gst_tag_list_get_buffer:
       
  1718  * @list: a #GstTagList to get the tag from
       
  1719  * @tag: tag to read out
       
  1720  * @value: address of a GstBuffer pointer variable to store the result into
       
  1721  *
       
  1722  * Copies the first buffer for the given tag in the taglist into the variable
       
  1723  * pointed to by @value. Free the buffer with gst_buffer_unref() when it is
       
  1724  * no longer needed.
       
  1725  *
       
  1726  * Returns: TRUE, if a buffer was copied, FALSE if the tag didn't exist in the
       
  1727  *              given list or if it was #NULL.
       
  1728  *
       
  1729  * Since: 0.10.23
       
  1730  */
       
  1731 #ifdef __SYMBIAN32__
       
  1732 EXPORT_C
       
  1733 #endif
       
  1734 
       
  1735 gboolean
       
  1736 gst_tag_list_get_buffer (const GstTagList * list, const gchar * tag,
       
  1737     GstBuffer ** value)
       
  1738 {
       
  1739   GValue v = { 0, };
       
  1740 
       
  1741   g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
       
  1742   g_return_val_if_fail (tag != NULL, FALSE);
       
  1743   g_return_val_if_fail (value != NULL, FALSE);
       
  1744 
       
  1745   if (!gst_tag_list_copy_value (&v, list, tag))
       
  1746     return FALSE;
       
  1747   *value = (GstBuffer *) gst_value_dup_mini_object (&v);
       
  1748   g_value_unset (&v);
       
  1749   return (*value != NULL);
       
  1750 }
       
  1751 
       
  1752 /**
       
  1753  * gst_tag_list_get_buffer_index:
       
  1754  * @list: a #GstTagList to get the tag from
       
  1755  * @tag: tag to read out
       
  1756  * @index: number of entry to read out
       
  1757  * @value: address of a GstBuffer pointer variable to store the result into
       
  1758  *
       
  1759  * Gets the buffer that is at the given index for the given tag in the given
       
  1760  * list and copies it into the variable pointed to by @value. Free the buffer
       
  1761  * with gst_buffer_unref() when it is no longer needed.
       
  1762  *
       
  1763  * Returns: TRUE, if a buffer was copied, FALSE if the tag didn't exist in the
       
  1764  *              given list or if it was #NULL.
       
  1765  *
       
  1766  * Since: 0.10.23
       
  1767  */
       
  1768 #ifdef __SYMBIAN32__
       
  1769 EXPORT_C
       
  1770 #endif
       
  1771 
       
  1772 gboolean
       
  1773 gst_tag_list_get_buffer_index (const GstTagList * list,
       
  1774     const gchar * tag, guint index, GstBuffer ** value)
       
  1775 {
       
  1776   const GValue *v;
       
  1777 
       
  1778   g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
       
  1779   g_return_val_if_fail (tag != NULL, FALSE);
       
  1780   g_return_val_if_fail (value != NULL, FALSE);
       
  1781 
       
  1782   if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
       
  1783     return FALSE;
       
  1784   *value = (GstBuffer *) gst_value_dup_mini_object (v);
       
  1785   return (*value != NULL);
       
  1786 }