docs/pwg/advanced-tagging.xml: Add a part about tag reading and application signallin...
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Thu, 29 Jan 2004 10:56:53 +0000 (10:56 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Thu, 29 Jan 2004 10:56:53 +0000 (10:56 +0000)
Original commit message from CVS:
2004-01-29  Ronald Bultje  <rbultje@ronald.bitfreak.net>

* 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):
We can set file locations in READY, too.

ChangeLog
docs/pwg/advanced-tagging.xml
gst/elements/gstfilesrc.c
plugins/elements/gstfilesrc.c

index dc39cb4..4b92f90 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2004-01-29  Ronald Bultje  <rbultje@ronald.bitfreak.net>
+
+       * 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):
+         We can set file locations in READY, too.
+
 2004-01-29  Julien MOUTTE <julien@moutte.net>
 
        * docs/random/ds/element-checklist: Adding some notes about src
index e894275..77a03b5 100644 (file)
   <sect1 id="section-tagging-read" xreflabel="Reading Tags from Streams">
     <title>Reading Tags from Streams</title>
     <para>
-      WRITEME
+      The basic object for tags is a <classname>GstTagList</classname>. 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
+      <function>gst_tag_list_new ()</function>. Then, the element can fill the
+      list using <function>gst_tag_list_add_values ()</function>. Note that
+      an element probably reads metadata as strings, but values might not
+      necessarily be strings. Be sure to use <function>gst_value_transform ()</function>
+      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
+      <function>gst_element_found_tags ()</function>. The tags should also be
+      part of the datastream, so they should be pushed over all source pads.
+      The function <function>gst_event_new_tag ()</function> creates an event
+      from a taglist. This can be pushed over source pads using
+      <function>gst_pad_push ()</function>. Simple elements with only one
+      source pad can combine all these steps all-in-one by using the function
+      <function>gst_element_found_tags_for_pad ()</function>.
+    </para>
+    <para>
+      The following example program will parse a file and parse the data as
+      metadata/tags rathen than as actual content-data. It will parse each
+      line as <quote>name:value</quote>, where name is the type of metadata
+      (title, author, ...) and value is the metadata value. The
+      <function>_getline ()</function> is the same as the one given in
+      <xref linkend="section-reqpad-sometimes"/>.
+    </para>
+    <programlisting>
+static void
+gst_my_filter_loopfunc (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 = &amp;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 (&amp;from, G_TYPE_STRING);
+      g_value_set_string (&amp;from, colon_pos);
+      g_value_init (&amp;to, to_type);
+      g_value_transform (&amp;from, &amp;to);
+      g_value_unset (&amp;from);
+      gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND,
+                              type, &amp;to, NULL);
+      g_value_unset (&amp;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);
+}
+    </programlisting>
+    <para>
+      We currently assume the core to already <emphasis>know</emphasis> the
+      mimetype (<function>gst_tag_exists ()</function>). You can add new tags
+      to the list of known tags using <function>gst_tag_register ()</function>.
+      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 <filename>gsttag.c</filename>
+      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 <function>_class_init ()</function>.
     </para>
+    <programlisting>
+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);
+[..]
+}
+    </programlisting>
   </sect1>
 
   <sect1 id="section-tagging-write" xreflabel="Writing Tags to Streams">
index b0f7a25..d933591 100644 (file)
@@ -257,7 +257,8 @@ static gboolean
 gst_filesrc_set_location (GstFileSrc *src, const gchar *location)
 {
   /* the element must be stopped in order to do this */
-  if (GST_STATE (src) != GST_STATE_NULL)
+  if (GST_STATE (src) != GST_STATE_READY &&
+      GST_STATE (src) != GST_STATE_NULL)
     return FALSE;
 
   if (src->filename) g_free (src->filename);
index b0f7a25..d933591 100644 (file)
@@ -257,7 +257,8 @@ static gboolean
 gst_filesrc_set_location (GstFileSrc *src, const gchar *location)
 {
   /* the element must be stopped in order to do this */
-  if (GST_STATE (src) != GST_STATE_NULL)
+  if (GST_STATE (src) != GST_STATE_READY &&
+      GST_STATE (src) != GST_STATE_NULL)
     return FALSE;
 
   if (src->filename) g_free (src->filename);