--- /home/ensonic/projects/gstreamer/gst-plugins-base/gst-libs/gst/tag/Makefile.am	2008-01-18 15:20:54.000000000 +0200
+++ ./gst-libs/gst/tag/Makefile.am	2008-10-23 16:11:50.000000000 +0300
@@ -8,7 +8,10 @@ lib_LTLIBRARIES = libgsttag-@GST_MAJORMI
 
 libgsttag_@GST_MAJORMINOR@_la_SOURCES = gstvorbistag.c gstid3tag.c tags.c gsttagdemux.c
 libgsttag_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
-libgsttag_@GST_MAJORMINOR@_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) 
+libgsttag_@GST_MAJORMINOR@_la_LIBADD = \
+	$(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-@GST_MAJORMINOR@.la \
+	$(GST_BASE_LIBS) $(GST_LIBS)
+
 libgsttag_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
 
 noinst_HEADERS = gsttageditingprivate.h
--- /home/ensonic/projects/gstreamer/gst-plugins-base/gst-libs/gst/tag/gsttagdemux.c	2008-10-06 17:20:49.000000000 +0300
+++ ./gst-libs/gst/tag/gsttagdemux.c	2008-12-11 16:39:54.000000000 +0200
@@ -75,6 +75,7 @@
 #include "gsttagdemux.h"
 
 #include <gst/base/gsttypefindhelper.h>
+#include <gst/interfaces/tagreader.h>
 #include <gst/gst-i18n-plugin.h>
 #include <string.h>
 
@@ -111,6 +112,7 @@ struct _GstTagDemuxPrivate
   GstSegment segment;
   gboolean need_newseg;
   gboolean newseg_update;
+  GstTagReadingMode tagread_mode;
 };
 
 /* Require at least 8kB of data before we attempt typefind. 
@@ -164,6 +166,24 @@ static void gst_tag_demux_init (GstTagDe
 static gpointer parent_class;   /* NULL */
 
 /* Cannot use boilerplate macros here because we want the abstract flag */
+
+static void
+gst_tag_demux_tagreader_mode (GstTagReader *reader,
+                              GstTagReadingMode mode)
+{
+  GstTagDemux * tagdemux;
+  tagdemux = GST_TAG_DEMUX (reader);
+  GST_DEBUG_OBJECT (tagdemux, "tag reading mode: %d", mode);
+  tagdemux->priv->tagread_mode = mode;
+}
+
+static void
+gst_tag_demux_tagreader_interface_init (GstTagReaderInterface * iface)
+{
+  /* set up the interface hooks */
+  iface->tag_reading_mode = gst_tag_demux_tagreader_mode;
+}
+
 GType
 gst_tag_demux_get_type (void)
 {
@@ -181,9 +201,18 @@ gst_tag_demux_get_type (void)
       0,                        /* n_preallocs */
       (GInstanceInitFunc) gst_tag_demux_init
     };
+    static const GInterfaceInfo tr_iface_info = {
+      (GInterfaceInitFunc) gst_tag_demux_tagreader_interface_init,
+       NULL,
+       NULL,
+    };
 
     object_type = g_type_register_static (GST_TYPE_ELEMENT,
         "GstTagDemux", &object_info, G_TYPE_FLAG_ABSTRACT);
+
+    g_type_add_interface_static (object_type,
+        GST_TYPE_TAGREADER, &tr_iface_info);
+
   }
 
   return object_type;
@@ -667,6 +696,10 @@ gst_tag_demux_chain (GstPad * pad, GstBu
           gst_tag_demux_send_tag_event (demux);
           demux->priv->send_tag_event = FALSE;
         }
+        /* tell the application not to wait for any tags from us anymore */
+        if (demux->priv->tagread_mode == GST_TAGREAD_MODE_TAGS) {
+          gst_tagreader_done (GST_TAGREADER (demux));
+        }
 
         /* Ensure the caps are set correctly */
         outbuf = gst_buffer_make_metadata_writable (outbuf);
@@ -893,6 +926,12 @@ gst_tag_demux_pull_end_tag (GstTagDemux 
 
     demux->priv->strip_end = tagsize;
 
+    if (demux->priv->tagread_mode == GST_TAGREAD_MODE_DATA) {
+      GST_DEBUG_OBJECT (demux, "Skipping end tags");
+      res = TRUE;
+      goto done;
+    }
+
     g_assert (tagsize >= klass->min_end_size);
 
     /* Get buffer that's exactly the requested size */
@@ -1017,6 +1056,12 @@ gst_tag_demux_pull_start_tag (GstTagDemu
 
     demux->priv->strip_start = tagsize;
 
+    if (demux->priv->tagread_mode == GST_TAGREAD_MODE_DATA) {
+      GST_DEBUG_OBJECT (demux, "Skipping start tags");
+      res = TRUE;
+      goto done;
+    }
+
     /* Now pull the entire tag */
     g_assert (tagsize >= klass->min_start_size);
 
@@ -1147,6 +1192,9 @@ gst_tag_demux_sink_activate (GstPad * si
   if (!e_tag_ok && !s_tag_ok)
     return FALSE;
 
+  /* FIXME: In tag reading mode we could send the tags here already.
+     TagReader interface could also be used to determine if data passing
+     is needed. If not, we could skip the typefind process and stop here. */
   if (demux->priv->parsed_tags != NULL) {
     demux->priv->send_tag_event = TRUE;
   }
@@ -1284,6 +1332,9 @@ gst_tag_demux_src_getrange (GstPad * src
   if (demux->priv->send_tag_event) {
     gst_tag_demux_send_tag_event (demux);
     demux->priv->send_tag_event = FALSE;
+    if (demux->priv->tagread_mode == GST_TAGREAD_MODE_TAGS) {
+      gst_tagreader_done (GST_TAGREADER (demux));
+    }
   }
 
   return gst_tag_demux_read_range (demux, offset, length, buffer);
