| Quoting iain <iain@prettypeople.org>: |
| |
| > 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 |
| |
| |