1 <chapter id="chapter-advanced-tagging">
2 <title>Tagging (Metadata and Streaminfo)</title>
4 Tags are pieces of information stored in a stream that are not the content
5 itself, butthey rather <emphasis>describe</emphasis> the content. Most
6 media container formats support tagging in one way or another. Ogg uses
7 VorbisComment for this, MP3 uses ID3, AVI and WAV use RIFF's INFO list
8 chunk, etc. GStreamer provides a general way for elements to read tags from
9 the stream and expose this to the user. The tags (at least the metadata)
10 will be part of the stream inside the pipeline. The consequence of this is
11 that transcoding of files from one format to another will automatically
12 preserve tags, as long as the input and output format elements both support
16 Tags are separated in two categories in GStreamer, even though applications
17 won't notice anything of this. The first are called <emphasis>metadata</emphasis>,
18 the second are called <emphasis>streaminfo</emphasis>. Metadata are tags
19 that describe the non-technical parts of stream content. They can be
20 changed without needing to re-encode the stream completely. Examples are
21 <quote>author</quote>, <quote>title</quote> or <quote>album</quote>. The
22 container format might still need to be re-written for the tags to fit in,
23 though. Streaminfo, on the other hand, are tags that describe the stream
24 contents technically. To change them, the stream needs to be re-encoded.
25 Examples are <quote>codec</quote> or <quote>bitrate</quote>. Note that some
26 container formats (like ID3) store various streaminfo tags as metadata in
27 the file container, which means that they can be changed so that they don't
28 match the content in the file anymore. Still, they are called metadata
29 because <emphasis>technically</emphasis>, they can be changed without
30 re-encoding the whole stream, even though that makes them invalid. Files
31 with such metadata tags will have the same tag twice: once as metadata,
35 A tag reading element is called <classname>TagGetter</classname> in
36 &GStreamer;. A tag writer is called <classname>TagSetter</classname>. An
37 element supporting both can be used in a tag editor for quick tag changing.
40 <sect1 id="section-tagging-read" xreflabel="Reading Tags from Streams">
41 <title>Reading Tags from Streams</title>
43 The basic object for tags is a <classname>GstTagList</classname>. An
44 element that is reading tags from a stream should create an empty taglist
45 and fill this with individual tags. Empty tag lists can be created with
46 <function>gst_tag_list_new ()</function>. Then, the element can fill the
47 list using <function>gst_tag_list_add_values ()</function>. Note that
48 an element probably reads metadata as strings, but values might not
49 necessarily be strings. Be sure to use <function>gst_value_transform ()</function>
50 to make sure that your data is of the right type. After data reading, the
51 application can be notified of the new taglist by calling
52 <function>gst_element_found_tags ()</function>. The tags should also be
53 part of the datastream, so they should be pushed over all source pads.
54 The function <function>gst_event_new_tag ()</function> creates an event
55 from a taglist. This can be pushed over source pads using
56 <function>gst_pad_push ()</function>. Simple elements with only one
57 source pad can combine all these steps all-in-one by using the function
58 <function>gst_element_found_tags_for_pad ()</function>.
61 The following example program will parse a file and parse the data as
62 metadata/tags rathen than as actual content-data. It will parse each
63 line as <quote>name:value</quote>, where name is the type of metadata
64 (title, author, ...) and value is the metadata value. The
65 <function>_getline ()</function> is the same as the one given in
66 <xref linkend="section-reqpad-sometimes"/>.
70 gst_my_filter_loopfunc (GstElement *element)
72 GstMyFilter *filter = GST_MY_FILTER (element);
74 GstTagList *taglist = gst_tag_list_new ();
76 /* get each line and parse as metadata */
77 while ((buf = gst_my_filter_getline (filter))) {
78 gchar *line = GST_BUFFER_DATA (buf), *colon_pos, *type = NULL;a
80 /* get the position of the ':' and go beyond it */
81 if (!(colon_pos = strchr (line, ':')))
84 /* get the string before that as type of metadata */
85 type = g_strndup (line, colon_pos - line);
87 /* content is one character beyond the ':' */
88 colon_pos = &colon_pos[1];
89 if (*colon_pos == '\0')
92 /* get the metadata category, it's value type, store it in that
93 * type and add it to the taglist. */
94 if (gst_tag_exists (type)) {
95 GValue from = { 0 }, to = { 0 };
98 to_type = gst_tag_get_type (type);
99 g_value_init (&from, G_TYPE_STRING);
100 g_value_set_string (&from, colon_pos);
101 g_value_init (&to, to_type);
102 g_value_transform (&from, &to);
103 g_value_unset (&from);
104 gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND,
105 type, &to, NULL);
106 g_value_unset (&to);
111 gst_buffer_unref (buf);
114 /* signal metadata */
115 gst_element_found_tags_for_pad (element, filter->srcpad, 0, taglist);
116 gst_tag_list_free (taglist);
119 gst_pad_send_event (filter->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
120 gst_element_set_eos (element);
124 We currently assume the core to already <emphasis>know</emphasis> the
125 mimetype (<function>gst_tag_exists ()</function>). You can add new tags
126 to the list of known tags using <function>gst_tag_register ()</function>.
127 If you think the tag will be useful in more cases than just your own
128 element, it might be a good idea to add it to <filename>gsttag.c</filename>
129 instead. That's up to you to decide. If you want to do it in your own
130 element, it's easiest to register the tag in one of your class init
131 functions, preferrably <function>_class_init ()</function>.
135 gst_my_filter_class_init (GstMyFilterClass *klass)
138 gst_tag_register ("my_tag_name", GST_TAG_FLAG_META,
141 _("a tag that is specific to my own element"),
148 <sect1 id="section-tagging-write" xreflabel="Writing Tags to Streams">
149 <title>Writing Tags to Streams</title>
151 Tag writers are the opposite of tag readers. Tag writers only take
152 metadata tags into account, since that's the only type of tags that have
153 to be written into a stream. Tag writers can receive tags in three ways:
154 internal, application and pipeline. Internal tags are tags read by the
155 element itself, which means that the tag writer is - in that case - a tag
156 reader, too. Application tags are tags provided to the element via the
157 TagSetter interface (which is just a layer). Pipeline tags are tags
158 provided to the element from within the pipeline. The element receives
159 such tags via the <classname>GST_EVENT_TAG</classname> event, which means
160 that tags writers should automatically be event aware. The tag writer is
161 responsible for combining all these three into one list and writing them
162 to the output stream.
165 The example below will receive tags from both application and pipeline,
166 combine them and write them to the output stream. It implements the tag
167 setter so applications can set tags, and retrieves pipeline tags from
172 gst_my_filter_get_type (void)
175 static const GInterfaceInfo tag_setter_info = {
181 g_type_add_interface_static (my_filter_type,
183 &tag_setter_info);
188 gst_my_filter_init (GstMyFilter *filter)
190 GST_FLAG_SET (filter, GST_ELEMENT_EVENT_AWARE);
199 gst_my_filter_write_tag (const GstTagList *taglist,
200 const gchar *tagname,
203 GstMyFilter *filter = GST_MY_FILTER (data);
205 guint num_values = gst_tag_list_get_tag_size (list, tag_name), n;
209 g_value_init (&to, G_TYPE_STRING);
211 for (n = 0; n < num_values; n++) {
212 from = gst_tag_list_get_value_index (taglist, tagname, n);
213 g_value_transform (from, &to);
215 buf = gst_buffer_new ();
216 GST_BUFFER_DATA (buf) = g_strdup_printf ("%s:%s", tagname,
217 g_value_get_string (&to));
218 GST_BUFFER_SIZE (buf) = strlen (GST_BUFFER_DATA (buf));
219 gst_pad_push (filter->srcpad, GST_DATA (buf));
222 g_value_unset (&to);
226 gst_my_filter_loopfunc (GstElement *element)
228 GstMyFilter *filter = GST_MY_FILTER (element);
229 GstTagSetter *tagsetter = GST_TAG_SETTER (element);
232 gboolean eos = FALSE;
233 GstTagList *taglist = gst_tag_list_new ();
236 data = gst_pad_pull (filter->sinkpad);
238 /* We're not very much interested in data right now */
239 if (GST_IS_BUFFER (data))
240 gst_buffer_unref (GST_BUFFER (data));
241 event = GST_EVENT (data);
243 switch (GST_EVENT_TYPE (event)) {
245 gst_tag_list_insert (taglist, gst_event_tag_get_list (event),
246 GST_TAG_MERGE_PREPEND);
247 gst_event_unref (event);
251 gst_event_unref (event);
254 gst_pad_event_default (filter->sinkpad, event);
259 /* merge tags with the ones retrieved from the application */
260 if (gst_tag_setter_get_list (tagsetter)) {
261 gst_tag_list_insert (taglist,
262 gst_tag_setter_get_list (tagsetter),
263 gst_tag_setter_get_merge_mode (tagsetter));
267 gst_tag_list_foreach (taglist, gst_my_filter_write_tag, filter);
270 gst_pad_push (filter->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
271 gst_element_set_eos (element);
275 Note that normally, elements would not read the full stream before
276 processing tags. Rather, they would read from each sinkpad until they've
277 received data (since tags usually come in before the first data buffer)