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