The basic object for tags is a GstTagList
. An element that is reading tags from a stream should
create an empty taglist and fill this with individual tags. Empty tag
lists can be created with gst_tag_list_new ()
. Then,
the element can fill the list using gst_tag_list_add ()
or gst_tag_list_add_values ()
.
Note that elements often read metadata as strings, but the
values in the taglist might not necessarily be strings - they need to be
of the type the tag was registered as (the API documentation for each
predefined tag should contain the type). Be sure to use functions like
gst_value_transform ()
to make sure that your data is of the right type. After data reading, the
application can be notified of the new taglist by calling
gst_element_found_tags ()
or
gst_element_found_tags_for_pad ()
(if they only
refer to a specific sub-stream). These functions will post a tag message
on the pipeline's GstBus for the application to pick up, but also send
tag events downstream, either over all source pad or the pad specified.
The following example program will parse a file and parse the data as
metadata/tags rather than as actual content-data. It will parse each
line as "name:value", where name is the type of metadata
(title, author, ...) and value is the metadata value. The
_getline ()
is the same as the one given in
Sometimes pads.
static void gst_my_filter_task_func (GstElement *element) { GstMyFilter *filter = GST_MY_FILTER (element); GstBuffer *buf; GstTagList *taglist = gst_tag_list_new (); /* get each line and parse as metadata */ while ((buf = gst_my_filter_getline (filter))) { gchar *line = GST_BUFFER_DATA (buf), *colon_pos, *type = NULL;a /* get the position of the ':' and go beyond it */ if (!(colon_pos = strchr (line, ':'))) goto next: /* get the string before that as type of metadata */ type = g_strndup (line, colon_pos - line); /* content is one character beyond the ':' */ colon_pos = &colon_pos[1]; if (*colon_pos == '\0') goto next; /* get the metadata category, it's value type, store it in that * type and add it to the taglist. */ if (gst_tag_exists (type)) { GValue from = { 0 }, to = { 0 }; GType to_type; to_type = gst_tag_get_type (type); g_value_init (&from, G_TYPE_STRING); g_value_set_string (&from, colon_pos); g_value_init (&to, to_type); g_value_transform (&from, &to); g_value_unset (&from); gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND, type, &to, NULL); g_value_unset (&to); } next: g_free (type); gst_buffer_unref (buf); } /* signal metadata */ gst_element_found_tags_for_pad (element, filter->srcpad, 0, taglist); gst_tag_list_free (taglist); /* send EOS */ gst_pad_send_event (filter->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS))); gst_element_set_eos (element); }
We currently assume the core to already know the
mimetype (gst_tag_exists ()
). You can add new tags
to the list of known tags using gst_tag_register ()
.
If you think the tag will be useful in more cases than just your own
element, it might be a good idea to add it to gsttag.c
instead. That's up to you to decide. If you want to do it in your own
element, it's easiest to register the tag in one of your class init
functions, preferrably _class_init ()
.
static void gst_my_filter_class_init (GstMyFilterClass *klass) { [..] gst_tag_register ("my_tag_name", GST_TAG_FLAG_META, G_TYPE_STRING, _("my own tag"), _("a tag that is specific to my own element"), NULL); [..] }