From 55072fb6110b345431c370072b4774cea6a328b8 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 29 Jan 2004 12:35:01 +0000 Subject: [PATCH] docs/pwg/advanced-tagging.xml: Add docs about tag writing. Original commit message from CVS: 2004-01-29 Ronald Bultje * docs/pwg/advanced-tagging.xml: Add docs about tag writing. --- ChangeLog | 5 ++ docs/pwg/advanced-tagging.xml | 129 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4b92f90..894187d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,11 @@ 2004-01-29 Ronald Bultje * docs/pwg/advanced-tagging.xml: + Add docs about tag writing. + +2004-01-29 Ronald Bultje + + * docs/pwg/advanced-tagging.xml: Add a part about tag reading and application signalling... Tag writing still needs to be documented. * gst/elements/gstfilesrc.c: (gst_filesrc_set_location): diff --git a/docs/pwg/advanced-tagging.xml b/docs/pwg/advanced-tagging.xml index b3e1b4f..e51c723 100644 --- a/docs/pwg/advanced-tagging.xml +++ b/docs/pwg/advanced-tagging.xml @@ -148,7 +148,134 @@ gst_my_filter_class_init (GstMyFilterClass *klass) Writing Tags to Streams - WRITEME + Tag writers are the opposite of tag readers. Tag writers only take + metadata tags into account, since that's the only type of tags that have + to be written into a stream. Tag writers can receive tags in three ways: + internal, application and pipeline. Internal tags are tags read by the + element itself, which means that the tag writer is - in that case - a tag + reader, too. Application tags are tags provided to the element via the + TagSetter interface (which is just a layer). Pipeline tags are tags + provided to the element from within the pipeline. The element receives + such tags via the GST_EVENT_TAG event, which means + that tags writers should automatically be event aware. The tag writer is + responsible for combining all these three into one list and writing them + to the output stream. + + + The example below will receive tags from both application and pipeline, + combine them and write them to the output stream. It implements the tag + setter so applications can set tags, and retrieves pipeline tags from + incoming events. + + +GType +gst_my_filter_get_type (void) +{ +[..] + static const GInterfaceInfo tag_setter_info = { + NULL, + NULL, + NULL + }; +[..] + g_type_add_interface_static (my_filter_type, + GST_TYPE_TAG_SETTER, + &tag_setter_info); +[..] +} + +static void +gst_my_filter_init (GstMyFilter *filter) +{ + GST_FLAG_SET (filter, GST_ELEMENT_EVENT_AWARE); +[..] +} + +/* + * Write one tag. + */ + +static void +gst_my_filter_write_tag (const GstTagList *taglist, + const gchar *tagname, + gpointer data) +{ + GstMyFilter *filter = GST_MY_FILTER (data); + GstBuffer *buffer; + guint num_values = gst_tag_list_get_tag_size (list, tag_name), n; + const GValue *from; + GValue to = { 0 }; + + g_value_init (&to, G_TYPE_STRING); + + for (n = 0; n < num_values; n++) { + from = gst_tag_list_get_value_index (taglist, tagname, n); + g_value_transform (from, &to); + + buf = gst_buffer_new (); + GST_BUFFER_DATA (buf) = g_strdup_printf ("%s:%s", tagname, + g_value_get_string (&to)); + GST_BUFFER_SIZE (buf) = strlen (GST_BUFFER_DATA (buf)); + gst_pad_push (filter->srcpad, GST_DATA (buf)); + } + + g_value_unset (&to); +} + +static void +gst_my_filter_loopfunc (GstElement *element) +{ + GstMyFilter *filter = GST_MY_FILTER (element); + GstTagSetter *tagsetter = GST_TAG_SETTER (element); + GstData *data; + GstEvent *event; + gboolean eos = FALSE; + GstTagList *taglist = gst_tag_list_new (); + + while (!eos) { + data = gst_pad_pull (filter->sinkpad); + + /* We're not very much interested in data right now */ + if (GST_IS_BUFFER (data)) + gst_buffer_unref (GST_BUFFER (data)); + event = GST_EVENT (data); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_TAG: + gst_tag_list_insert (taglist, gst_event_tag_get_list (event), + GST_TAG_MERGE_PREPEND); + gst_event_unref (event); + break; + case GST_EVENT_EOS: + eos = TRUE; + gst_event_unref (event); + break; + default: + gst_pad_event_default (filter->sinkpad, event); + break; + } + } + + /* merge tags with the ones retrieved from the application */ + if (gst_tag_setter_get_list (tagsetter)) { + gst_tag_list_insert (taglist, + gst_tag_setter_get_list (tagsetter), + gst_tag_setter_get_merge_mode (tagsetter)); + } + + /* write tags */ + gst_tag_list_foreach (taglist, gst_my_filter_write_tag, filter); + + /* signal EOS */ + gst_pad_push (filter->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS))); + gst_element_set_eos (element); +} + + + Note that normally, elements would not read the full stream before + processing tags. Rather, they would read from each sinkpad until they've + received data (since tags usually come in before the first data buffer) + and process that. -- 2.7.4