Tagreading
----------

The tagreading (metadata reading) use case for mediacenter applications is not
too well supported by the current GStreamer architecture. It uses demuxers on the
files, which generally said takes too long (building seek-index, prerolling).
What we want is specialized elements / parsing modes that just do the
tag-reading.

The idea is to define a TagReadIFace. Tag-demuxers, classic demuxers and decoder
plugins can just implement the interface or provide a separate element that
implements the interface.

In addition we need a tagreadbin, that similar to decodebin does a typefind and
then plugs the right tagread element(s). If will only look at elements that
implement the interface. It can plug serval if possible.

For optimal performance typefind and tagread could share the list of already
peeked buffers (a queue element after sink, but that would change pull to push).


Design
~~~~~~

The plan is that applications can do the following:
  pipeline = "filesrc ! tagbin"
  for (file_path in list_of_files) {
    filesrc.location=file_path
    pipeline.set_state(PAUSED)
    // wait for TAGS & EOS
    pipeline.set_state(READY)
  }

* it should have one sinkpad of type ANY
* it should send EOS when all metadata has been read
  "done"-signal from all tagread-elements
* special tagread-elements should have RANK_NONE to be not autoplugged by
  decodebin

Interface
~~~~~~~~~

* gboolean iface property "tag-reading"
  Switches the element to tagreading mode. Needed if normal element implement
  that behaviour. Elements will skip parsing unneeded data, don't build a
  seeking index, etc.
* signal "done"
  Equivalent of EOS.

Use Cases
~~~~~~~~~

* mp3 with id3- and apetags
  * plug id3demux ! apedemux
* avi with vorbis audio
  * plug avidemux
  * new pad -> audio/vorbis
  * plug vorbisdec or special vorbiscomment reader

Additional Thoughts
~~~~~~~~~~~~~~~~~~~

* would it make sense to have 2-phase tag-reading (property on tagbin and/or
  tagread elements)
  * 1st phase: get tag-data that are directly embedded in the data
  * 2nd phase: get tag-data that has to be generated
    * e.g. album-art via web, video-thumbnails
* what about caching backends
  * it would be good to allow applications to supply tagbin with a tagcache-
    object instance. Whenever tagbin gets a 'location' to tagread, it consults
    the cache first. whenever there is a cache-miss it will tag-read and then
    store in the cache

    GstTagList *gst_tag_cache_load_tag_data (GstTagCache *self, const gchar *uri);
    gst_tag_cache_store_tag_data (GstTagCache *self, const gchar *uri, GstTagList *tags);

Tests
~~~~~

* write a generic test for parsers/demuxers to ensure they send tags until they
  reached PAUSED (elements need to parse file for prerolling anyway):
  set pipeline to paused, check for tags, set to playing, error out if tags come
  after paused

Code Locations
~~~~~~~~~~~~~~

* tagreadbin -> gst-plugins-base/gst/tagread
* tagreaderiface -> gst-plugins-base/gst-libs/gst/tag

Reuse
~~~~~

* ogg : gst-plugins-base/ext/ogg
* avi : gst-plugins-good/gst/avi
* mp3 : gst-plugins-good/gst/id3demux
* wav : gst-plugins-good/gst/wavparse
* qt  : gst-plugins-bad/gst/qtdemux

