Git init
[framework/multimedia/gstreamer0.10.git] / docs / pwg / advanced-tagging.xml
1 <chapter id="chapter-advanced-tagging">
2   <title>Tagging (Metadata and Streaminfo)</title>
3
4   <sect1 id="section-tagging-overview" xreflabel="Overview">
5   <title>Overview</title>
6   <para>
7     Tags are pieces of information stored in a stream that are not the content
8     itself, but they rather <emphasis>describe</emphasis> the content. Most
9     media container formats support tagging in one way or another. Ogg uses
10     VorbisComment for this, MP3 uses ID3, AVI and WAV use RIFF's INFO list
11     chunk, etc. GStreamer provides a general way for elements to read tags from
12     the stream and expose this to the user. The tags (at least the metadata)
13     will be part of the stream inside the pipeline. The consequence of this is
14     that transcoding of files from one format to another will automatically
15     preserve tags, as long as the input and output format elements both support
16     tagging.
17   </para>
18   <para>
19     Tags are separated in two categories in GStreamer, even though applications
20     won't notice anything of this. The first are called <emphasis>metadata</emphasis>,
21     the second are called <emphasis>streaminfo</emphasis>. Metadata are tags
22     that describe the non-technical parts of stream content. They can be
23     changed without needing to re-encode the stream completely. Examples are
24     <quote>author</quote>, <quote>title</quote> or <quote>album</quote>. The
25     container format might still need to be re-written for the tags to fit in,
26     though. Streaminfo, on the other hand, are tags that describe the stream
27     contents technically. To change them, the stream needs to be re-encoded.
28     Examples are <quote>codec</quote> or <quote>bitrate</quote>. Note that some
29     container formats (like ID3) store various streaminfo tags as metadata in
30     the file container, which means that they can be changed so that they don't
31     match the content in the file any more. Still, they are called metadata
32     because <emphasis>technically</emphasis>, they can be changed without
33     re-encoding the whole stream, even though that makes them invalid. Files
34     with such metadata tags will have the same tag twice: once as metadata,
35     once as streaminfo.
36   </para>
37   <para>
38     There is no special name for tag reading elements in &GStreamer;. There are
39     specialised elements (e.g. id3demux) that do nothing besides tag reading,
40     but any  &GStreamer; element may extract tags while processing data, and
41     most decoders, demuxers and parsers do.
42   </para>
43   <para>
44     A tag writer is called <ulink type="http"
45     url="../../gstreamer/html/GstTagSetter.html"><classname>TagSetter</classname></ulink>.
46     An element supporting both can be used in a tag editor for quick tag
47     changing (note: in-place tag editing is still poorly supported at the time
48     of writing and usually requires tag extraction/stripping and remuxing of
49     the stream with new tags).
50   </para>
51   </sect1>
52
53   <sect1 id="section-tagging-read" xreflabel="Reading Tags from Streams">
54     <title>Reading Tags from Streams</title>
55     <para>
56       The basic object for tags is a <ulink type="http"
57       url="../../gstreamer/html/gstreamer-GstTagList.html"><classname>GstTagList
58       </classname></ulink>. An element that is reading tags from a stream should
59       create an empty taglist and fill this with individual tags. Empty tag
60       lists can be created with <function>gst_tag_list_new ()</function>. Then,
61       the element can fill the list using <function>gst_tag_list_add ()
62       </function> or <function>gst_tag_list_add_values ()</function>.
63       Note that elements often read metadata as strings, but the
64       values in the taglist might not necessarily be strings - they need to be
65       of the type the tag was registered as (the API documentation for each
66       predefined tag should contain the type). Be sure to use functions like
67       <function>gst_value_transform ()</function>
68       to make sure that your data is of the right type. After data reading, the
69       application can be notified of the new taglist by calling
70       <function>gst_element_found_tags ()</function> or
71       <function>gst_element_found_tags_for_pad ()</function> (if they only
72       refer to a specific sub-stream). These functions will post a tag message
73       on the pipeline's GstBus for the application to pick up, but also send
74       tag events downstream, either over all source pad or the pad specified.
75     </para>
76     <para>
77       We currently require the core to know the GType of tags before they are
78       being used, so all tags must be registered first.  You can add new tags
79       to the list of known tags using <function>gst_tag_register ()</function>.
80       If you think the tag will be useful in more cases than just your own
81       element, it might be a good idea to add it to <filename>gsttag.c</filename>
82       instead. That's up to you to decide. If you want to do it in your own
83       element, it's easiest to register the tag in one of your class init
84       functions, preferrably <function>_class_init ()</function>.
85     </para>
86     <programlisting>
87 <![CDATA[
88 static void
89 gst_my_filter_class_init (GstMyFilterClass *klass)
90 {
91 [..]
92   gst_tag_register ("my_tag_name", GST_TAG_FLAG_META,
93                     G_TYPE_STRING,
94                     _("my own tag"),
95                     _("a tag that is specific to my own element"),
96                     NULL);
97 [..]
98 }
99 ]]>
100     </programlisting>
101   </sect1>
102
103   <sect1 id="section-tagging-write" xreflabel="Writing Tags to Streams">
104     <title>Writing Tags to Streams</title>
105     <para>
106       Tag writers are the opposite of tag readers. Tag writers only take
107       metadata tags into account, since that's the only type of tags that have
108       to be written into a stream. Tag writers can receive tags in three ways:
109       internal, application and pipeline. Internal tags are tags read by the
110       element itself, which means that the tag writer is - in that case - a tag
111       reader, too. Application tags are tags provided to the element via the
112       TagSetter interface (which is just a layer). Pipeline tags are tags
113       provided to the element from within the pipeline. The element receives
114       such tags via the <symbol>GST_EVENT_TAG</symbol> event, which means
115       that tags writers should automatically be event aware. The tag writer is
116       responsible for combining all these three into one list and writing them
117       to the output stream.
118     </para>
119     <para>
120       The example below will receive tags from both application and pipeline,
121       combine them and write them to the output stream. It implements the tag
122       setter so applications can set tags, and retrieves pipeline tags from
123       incoming events.
124     </para>
125     <programlisting>
126 <![CDATA[
127 GType
128 gst_my_filter_get_type (void)
129 {
130 [..]
131     static const GInterfaceInfo tag_setter_info = {
132       NULL,
133       NULL,
134       NULL
135     };
136 [..]
137     g_type_add_interface_static (my_filter_type,
138                                  GST_TYPE_TAG_SETTER,
139                                  &tag_setter_info);
140 [..]
141 }
142
143 static void
144 gst_my_filter_init (GstMyFilter *filter)
145 {
146   GST_FLAG_SET (filter, GST_ELEMENT_EVENT_AWARE);
147 [..]
148 }
149
150 /*
151  * Write one tag.
152  */
153
154 static void
155 gst_my_filter_write_tag (const GstTagList *taglist,
156                          const gchar      *tagname,
157                          gpointer          data)
158 {
159   GstMyFilter *filter = GST_MY_FILTER (data);
160   GstBuffer *buffer;
161   guint num_values = gst_tag_list_get_tag_size (list, tag_name), n;
162   const GValue *from;
163   GValue to = { 0 };
164
165   g_value_init (&to, G_TYPE_STRING);
166
167   for (n = 0; n < num_values; n++) {
168     from = gst_tag_list_get_value_index (taglist, tagname, n);
169     g_value_transform (from, &to);
170
171     buf = gst_buffer_new ();
172     GST_BUFFER_DATA (buf) = g_strdup_printf ("%s:%s", tagname,
173                                              g_value_get_string (&to));
174     GST_BUFFER_SIZE (buf) = strlen (GST_BUFFER_DATA (buf));
175     gst_pad_push (filter->srcpad, GST_DATA (buf));
176   }
177
178   g_value_unset (&to);
179 }
180
181 static void
182 gst_my_filter_task_func (GstElement *element)
183 {
184   GstMyFilter *filter = GST_MY_FILTER (element);
185   GstTagSetter *tagsetter = GST_TAG_SETTER (element);
186   GstData *data;
187   GstEvent *event;
188   gboolean eos = FALSE;
189   GstTagList *taglist = gst_tag_list_new ();
190
191   while (!eos) {
192     data = gst_pad_pull (filter->sinkpad);
193
194     /* We're not very much interested in data right now */
195     if (GST_IS_BUFFER (data))
196       gst_buffer_unref (GST_BUFFER (data));
197     event = GST_EVENT (data);
198
199     switch (GST_EVENT_TYPE (event)) {
200       case GST_EVENT_TAG:
201         gst_tag_list_insert (taglist, gst_event_tag_get_list (event),
202                              GST_TAG_MERGE_PREPEND);
203         gst_event_unref (event);
204         break;
205       case GST_EVENT_EOS:
206         eos = TRUE;
207         gst_event_unref (event);
208         break;
209       default:
210         gst_pad_event_default (filter->sinkpad, event);
211         break;
212     }
213   }
214
215   /* merge tags with the ones retrieved from the application */
216   if ((gst_tag_setter_get_tag_list (tagsetter)) {
217     gst_tag_list_insert (taglist,
218                          gst_tag_setter_get_tag_list (tagsetter),
219                          gst_tag_setter_get_tag_merge_mode (tagsetter));
220   }
221
222   /* write tags */
223   gst_tag_list_foreach (taglist, gst_my_filter_write_tag, filter);
224
225   /* signal EOS */
226   gst_pad_push (filter->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
227   gst_element_set_eos (element);
228 }
229 ]]>
230     </programlisting>
231     <para>
232       Note that normally, elements would not read the full stream before
233       processing tags. Rather, they would read from each sinkpad until they've
234       received data (since tags usually come in before the first data buffer)
235       and process that.
236     </para>
237   </sect1>
238 </chapter>