fix non-validating docbook make sure validation gets checked before building
[platform/upstream/gstreamer.git] / docs / pwg / advanced-tagging.xml
1 <chapter id="chapter-advanced-tagging">
2   <title>Tagging (Metadata and Streaminfo)</title>
3   <para>
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
13     tagging.
14   </para>
15   <para>
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,
32     once as streaminfo.
33   </para>
34   <para>
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.
38   </para>
39
40   <sect1 id="section-tagging-read" xreflabel="Reading Tags from Streams">
41     <title>Reading Tags from Streams</title>
42     <para>
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>.
59     </para>
60     <para>
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"/>.
67     </para>
68     <programlisting>
69 <![CDATA[
70 static void
71 gst_my_filter_loopfunc (GstElement *element)
72 {
73   GstMyFilter *filter = GST_MY_FILTER (element);
74   GstBuffer *buf;
75   GstTagList *taglist = gst_tag_list_new ();
76
77   /* get each line and parse as metadata */
78   while ((buf = gst_my_filter_getline (filter))) {
79     gchar *line = GST_BUFFER_DATA (buf), *colon_pos, *type = NULL;a
80
81     /* get the position of the ':' and go beyond it */
82     if (!(colon_pos = strchr (line, ':')))
83       goto next:
84
85     /* get the string before that as type of metadata */
86     type = g_strndup (line, colon_pos - line);
87
88     /* content is one character beyond the ':' */
89     colon_pos = &colon_pos[1];
90     if (*colon_pos == '\0')
91       goto next;
92
93     /* get the metadata category, it's value type, store it in that
94      * type and add it to the taglist. */
95     if (gst_tag_exists (type)) {
96       GValue from = { 0 }, to = { 0 };
97       GType to_type;
98
99       to_type = gst_tag_get_type (type);
100       g_value_init (&from, G_TYPE_STRING);
101       g_value_set_string (&from, colon_pos);
102       g_value_init (&to, to_type);
103       g_value_transform (&from, &to);
104       g_value_unset (&from);
105       gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND,
106                                type, &to, NULL);
107       g_value_unset (&to);
108     }
109
110 next:
111     g_free (type);
112     gst_buffer_unref (buf);
113   }
114
115   /* signal metadata */
116   gst_element_found_tags_for_pad (element, filter->srcpad, 0, taglist);
117   gst_tag_list_free (taglist);
118
119   /* send EOS */
120   gst_pad_send_event (filter->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
121   gst_element_set_eos (element);
122 }
123 ]]>
124     </programlisting>
125     <para>
126       We currently assume the core to already <emphasis>know</emphasis> the
127       mimetype (<function>gst_tag_exists ()</function>). You can add new tags
128       to the list of known tags using <function>gst_tag_register ()</function>.
129       If you think the tag will be useful in more cases than just your own
130       element, it might be a good idea to add it to <filename>gsttag.c</filename>
131       instead. That's up to you to decide. If you want to do it in your own
132       element, it's easiest to register the tag in one of your class init
133       functions, preferrably <function>_class_init ()</function>.
134     </para>
135     <programlisting>
136 <![CDATA[
137 static void
138 gst_my_filter_class_init (GstMyFilterClass *klass)
139 {
140 [..]
141   gst_tag_register ("my_tag_name", GST_TAG_FLAG_META,
142                     G_TYPE_STRING,
143                     _("my own tag"),
144                     _("a tag that is specific to my own element"),
145                     NULL);
146 [..]
147 }
148 ]]>
149     </programlisting>
150   </sect1>
151
152   <sect1 id="section-tagging-write" xreflabel="Writing Tags to Streams">
153     <title>Writing Tags to Streams</title>
154     <para>
155       Tag writers are the opposite of tag readers. Tag writers only take
156       metadata tags into account, since that's the only type of tags that have
157       to be written into a stream. Tag writers can receive tags in three ways:
158       internal, application and pipeline. Internal tags are tags read by the
159       element itself, which means that the tag writer is - in that case - a tag
160       reader, too. Application tags are tags provided to the element via the
161       TagSetter interface (which is just a layer). Pipeline tags are tags
162       provided to the element from within the pipeline. The element receives
163       such tags via the <classname>GST_EVENT_TAG</classname> event, which means
164       that tags writers should automatically be event aware. The tag writer is
165       responsible for combining all these three into one list and writing them
166       to the output stream.
167     </para>
168     <para>
169       The example below will receive tags from both application and pipeline,
170       combine them and write them to the output stream. It implements the tag
171       setter so applications can set tags, and retrieves pipeline tags from
172       incoming events.
173     </para>
174     <programlisting>
175 <![CDATA[
176 GType
177 gst_my_filter_get_type (void)
178 {
179 [..]
180     static const GInterfaceInfo tag_setter_info = {
181       NULL,
182       NULL,
183       NULL
184     };
185 [..]
186     g_type_add_interface_static (my_filter_type,
187                                  GST_TYPE_TAG_SETTER,
188                                  &tag_setter_info);
189 [..]
190 }
191
192 static void
193 gst_my_filter_init (GstMyFilter *filter)
194 {
195   GST_FLAG_SET (filter, GST_ELEMENT_EVENT_AWARE);
196 [..]
197 }
198
199 /*
200  * Write one tag.
201  */
202
203 static void
204 gst_my_filter_write_tag (const GstTagList *taglist,
205                          const gchar      *tagname,
206                          gpointer          data)
207 {
208   GstMyFilter *filter = GST_MY_FILTER (data);
209   GstBuffer *buffer;
210   guint num_values = gst_tag_list_get_tag_size (list, tag_name), n;
211   const GValue *from;
212   GValue to = { 0 };
213
214   g_value_init (&to, G_TYPE_STRING);
215
216   for (n = 0; n < num_values; n++) {
217     from = gst_tag_list_get_value_index (taglist, tagname, n);
218     g_value_transform (from, &to);
219
220     buf = gst_buffer_new ();
221     GST_BUFFER_DATA (buf) = g_strdup_printf ("%s:%s", tagname,
222                                              g_value_get_string (&to));
223     GST_BUFFER_SIZE (buf) = strlen (GST_BUFFER_DATA (buf));
224     gst_pad_push (filter->srcpad, GST_DATA (buf));
225   }
226
227   g_value_unset (&to);
228 }
229
230 static void
231 gst_my_filter_loopfunc (GstElement *element)
232 {
233   GstMyFilter *filter = GST_MY_FILTER (element);
234   GstTagSetter *tagsetter = GST_TAG_SETTER (element);
235   GstData *data;
236   GstEvent *event;
237   gboolean eos = FALSE;
238   GstTagList *taglist = gst_tag_list_new ();
239
240   while (!eos) {
241     data = gst_pad_pull (filter->sinkpad);
242
243     /* We're not very much interested in data right now */
244     if (GST_IS_BUFFER (data))
245       gst_buffer_unref (GST_BUFFER (data));
246     event = GST_EVENT (data);
247
248     switch (GST_EVENT_TYPE (event)) {
249       case GST_EVENT_TAG:
250         gst_tag_list_insert (taglist, gst_event_tag_get_list (event),
251                              GST_TAG_MERGE_PREPEND);
252         gst_event_unref (event);
253         break;
254       case GST_EVENT_EOS:
255         eos = TRUE;
256         gst_event_unref (event);
257         break;
258       default:
259         gst_pad_event_default (filter->sinkpad, event);
260         break;
261     }
262   }
263
264   /* merge tags with the ones retrieved from the application */
265   if (gst_tag_setter_get_list (tagsetter)) {
266     gst_tag_list_insert (taglist,
267                          gst_tag_setter_get_list (tagsetter),
268                          gst_tag_setter_get_merge_mode (tagsetter));
269   }
270
271   /* write tags */
272   gst_tag_list_foreach (taglist, gst_my_filter_write_tag, filter);
273
274   /* signal EOS */
275   gst_pad_push (filter->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
276   gst_element_set_eos (element);
277 }
278 ]]>
279     </programlisting>
280     <para>
281       Note that normally, elements would not read the full stream before
282       processing tags. Rather, they would read from each sinkpad until they've
283       received data (since tags usually come in before the first data buffer)
284       and process that.
285     </para>
286   </sect1>
287 </chapter>