mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-26 18:20:44 +00:00
Add Company's email about tagging
Original commit message from CVS: Add Company's email about tagging
This commit is contained in:
parent
e19067d541
commit
1bb63cae00
1 changed files with 104 additions and 0 deletions
104
docs/random/company/tagging
Normal file
104
docs/random/company/tagging
Normal file
|
@ -0,0 +1,104 @@
|
|||
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
|
||||
|
||||
|
Loading…
Reference in a new issue