Quoting iain : > If you could write a small thing about how to use the tagging, it'd be > appreciated. I think MArlin is going to be using it pretty extensivly, > and so it'd be nice to get it in there and tested quickly. > Ok. A short writeup. Oh! Intro - Jellyman, offspring. Offspring, Jellyman. GStreamer manages tags in the form of GstTagList objects. A GstTagList (named taglist from now on) consists of zero or more different tags (this will be what I mean when I say tag) where each tag has one or more values attached to it. A tag is registered via gst_tag_register with it's name, translated name (glib calls that nick), a translated description, the GType values for this tag must have and an optional merge function. GStreamer provides default caps which are registered in gsttag.c. You can look them up there. You've got serious thrill issues, dude. A taglist is primarily thought about as a 1:1 tag:value mapping. Sometimes it is useful to have multiple values for the same tag however. (Multiple artists performing a song). If a merge function is provided at tag registration time, you can attach multiple values to a tag. These values are handled as an ordered list, so you can access each of them with an index. The merge function allows to merge all of them back into a single value. If no merge function is provided, only a single value is kept. Tell me, Dory, do you see anything? - Yeah, I see a light. There's a whole lot of API provided to change taglists. see gsttag.h for the whole glory. Most of that should be self explaining. Foreach functions, number of values per tag, getting tags and so on. The gst-launch code shows a usage example. The only thing that might be of interest is the merge mode. If you merge two tag lists (via _merge or _insert or even when only adding values via _add_tag) you have to provide a merge mode. The merge mode decides how to handle the merging of caps. If you merge new_tags into old_tags, the different merge modes do this: GST_TAG_MERGE_MODE_REPLACE_ALL: Remove all tags from old_tags, use only new_tags. GST_TAG_MERGE_MODE_REPLACE: Remove all tags from old_tags where tags from new_tags are available. Keep the others. Insert everything from new_tags. GST_TAG_MERGE_MODE_PREPEND: Prepend values from new_tags to the values from old_tags. For single value tags when both are set, use the new_tags tag. GST_TAG_MERGE_MODE_APPEND: Same as GST_TAG_MERGE_MODE_PREPEND with new_tags and old_tags swapped. GST_TAG_MERGE_MODE_KEEP: Same as GST_TAG_MERGE_MODE_REPLACE with new_tags and old_tags swapped. GST_TAG_MERGE_MODE_KEEP_ALL: Same as GST_TAG_MERGE_MODE_REPLACE_ALL with new_tags and old_tags swapped. This allows some powerful usage of taglists. I'll describe further down where it really makes sense. Now what? There are supposed to be two "producers" of taglists. The first are applications, the second are plugins. (In my tag world domination plans I simply assumed Rhythmbox would start using taglists internally.) Applications can easily create and access them with the API shown above. It should even be reasonably easy to put their values inside gtk objects via foreach loops and similar. Especially because they're all just GValues internally. Plugins extract tag lists from the GstBuffer data. They'll have to convert it to taglists obviously. (If you write plugins, please make sure to use the same mapping than other plugins that use the same format. Mappings and plugins for common tagging formats are kept in gst-plugins/gst/tags/* ) Once they have extracted the taglist, they signal they have found tags via the "found-tag" signal. After that they create a tag event and send that down the pipeline. There are convenience functions for this. See code that implements this. Oh, look at me, I'm a flippy little dolphin, let me flip for you! There are also supposed to be two "consumers" of taglists. Applications and - you guessed it - plugins. Applications obviously want to show the tags of the playing pipeline or store tags for a given file, use them as the basis for editing or whatever. Plugins that can set tags implement the GstTagSetter interface. Don't let yourself be fooled by the fact that this interface is an empty interface. Your plugin still has to do something. ;) The interface provides a way to attach tags to elements implementing the interface. Whenever the interface wants to write tags it has to do the following: 1) Get the tags from the pipeline that you want to write. (This obviously includes storing tags that came in via tag events.) 2) Merge the user set tags into these tags with the user set merge mode. This is the place where the merge mode allows all te flexibility you may want: adding tags, adding values to tags, overwriting all tags or overwriting only some tags. 3) Write these tags to the buffer. Hey! You guys made me ink! I hope this exciting little intro answered some of your questions. If not, ask more specific questions next time, please. :) Benjamin