/* GStreamer Matroska muxer/demuxer
 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * (c) 2006 Tim-Philipp Müller <tim centricular net>
 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
 * (c) 2011 Debarshi Ray <rishi@gnu.org>
 *
 * matroska-read-common.c: shared by matroska file/stream demuxer and parser
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>

#ifdef HAVE_ZLIB
#include <zlib.h>
#endif

#ifdef HAVE_BZ2
#include <bzlib.h>
#endif

#include <gst/tag/tag.h>
#include <gst/base/gsttypefindhelper.h>

#include "lzo.h"

#include "ebml-read.h"
#include "matroska-read-common.h"
#include "matroska-ids.h"

GST_DEBUG_CATEGORY (matroskareadcommon_debug);
#define GST_CAT_DEFAULT matroskareadcommon_debug

#define DEBUG_ELEMENT_START(common, ebml, element) \
    GST_DEBUG_OBJECT (common->sinkpad, "Parsing " element " element at offset %" \
        G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))

#define DEBUG_ELEMENT_STOP(common, ebml, element, ret) \
    GST_DEBUG_OBJECT (common->sinkpad, "Parsing " element " element " \
        " finished with '%s'", gst_flow_get_name (ret))

#define GST_MATROSKA_TOC_UID_CHAPTER "chapter"
#define GST_MATROSKA_TOC_UID_EDITION "edition"
#define GST_MATROSKA_TOC_UID_EMPTY "empty"

typedef struct
{
  GstTagList *result;
  guint64 target_type_value;
  gchar *target_type;
  gboolean audio_only;
} TargetTypeContext;


static gboolean
gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
    gpointer * data_out, gsize * size_out,
    GstMatroskaTrackCompressionAlgorithm algo)
{
  guint8 *new_data = NULL;
  guint new_size = 0;
  guint8 *data = *data_out;
  guint size = *size_out;
  gboolean ret = TRUE;

  if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
#ifdef HAVE_ZLIB
    /* zlib encoded data */
    z_stream zstream;
    guint orig_size;
    int result;

    orig_size = size;
    zstream.zalloc = (alloc_func) 0;
    zstream.zfree = (free_func) 0;
    zstream.opaque = (voidpf) 0;
    if (inflateInit (&zstream) != Z_OK) {
      GST_WARNING ("zlib initialization failed.");
      ret = FALSE;
      goto out;
    }
    zstream.next_in = (Bytef *) data;
    zstream.avail_in = orig_size;
    new_size = orig_size;
    new_data = g_malloc (new_size);
    zstream.avail_out = new_size;
    zstream.next_out = (Bytef *) new_data;

    do {
      result = inflate (&zstream, Z_NO_FLUSH);
      if (result != Z_OK && result != Z_STREAM_END) {
        GST_WARNING ("zlib decompression failed.");
        g_free (new_data);
        inflateEnd (&zstream);
        break;
      }
      new_size += 4000;
      new_data = g_realloc (new_data, new_size);
      zstream.next_out = (Bytef *) (new_data + zstream.total_out);
      zstream.avail_out += 4000;
    } while (zstream.avail_in != 0 && result != Z_STREAM_END);

    if (result != Z_STREAM_END) {
      ret = FALSE;
      goto out;
    } else {
      new_size = zstream.total_out;
      inflateEnd (&zstream);
    }
#else
    GST_WARNING ("zlib encoded tracks not supported.");
    ret = FALSE;
    goto out;
#endif
  } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
#ifdef HAVE_BZ2
    /* bzip2 encoded data */
    bz_stream bzstream;
    guint orig_size;
    int result;

    bzstream.bzalloc = NULL;
    bzstream.bzfree = NULL;
    bzstream.opaque = NULL;
    orig_size = size;

    if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
      GST_WARNING ("bzip2 initialization failed.");
      ret = FALSE;
      goto out;
    }

    bzstream.next_in = (char *) data;
    bzstream.avail_in = orig_size;
    new_size = orig_size;
    new_data = g_malloc (new_size);
    bzstream.avail_out = new_size;
    bzstream.next_out = (char *) new_data;

    do {
      result = BZ2_bzDecompress (&bzstream);
      if (result != BZ_OK && result != BZ_STREAM_END) {
        GST_WARNING ("bzip2 decompression failed.");
        g_free (new_data);
        BZ2_bzDecompressEnd (&bzstream);
        break;
      }
      new_size += 4000;
      new_data = g_realloc (new_data, new_size);
      bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
      bzstream.avail_out += 4000;
    } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);

    if (result != BZ_STREAM_END) {
      ret = FALSE;
      goto out;
    } else {
      new_size = bzstream.total_out_lo32;
      BZ2_bzDecompressEnd (&bzstream);
    }
#else
    GST_WARNING ("bzip2 encoded tracks not supported.");
    ret = FALSE;
    goto out;
#endif
  } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
    /* lzo encoded data */
    int result;
    int orig_size, out_size;

    orig_size = size;
    out_size = size;
    new_size = size;
    new_data = g_malloc (new_size);

    do {
      orig_size = size;
      out_size = new_size;

      result = lzo1x_decode (new_data, &out_size, data, &orig_size);

      if (orig_size > 0) {
        new_size += 4000;
        new_data = g_realloc (new_data, new_size);
      }
    } while (orig_size > 0 && result == LZO_OUTPUT_FULL);

    new_size -= out_size;

    if (result != LZO_OUTPUT_FULL) {
      GST_WARNING ("lzo decompression failed");
      g_free (new_data);

      ret = FALSE;
      goto out;
    }

  } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
    /* header stripped encoded data */
    if (enc->comp_settings_length > 0) {
      new_data = g_malloc (size + enc->comp_settings_length);
      new_size = size + enc->comp_settings_length;

      memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
      memcpy (new_data + enc->comp_settings_length, data, size);
    }
  } else {
    GST_ERROR ("invalid compression algorithm %d", algo);
    ret = FALSE;
  }

out:

  if (!ret) {
    *data_out = NULL;
    *size_out = 0;
  } else {
    *data_out = new_data;
    *size_out = new_size;
  }

  return ret;
}

GstFlowReturn
gst_matroska_decode_content_encodings (GArray * encodings)
{
  gint i;

  if (encodings == NULL)
    return GST_FLOW_OK;

  for (i = 0; i < encodings->len; i++) {
    GstMatroskaTrackEncoding *enc =
        &g_array_index (encodings, GstMatroskaTrackEncoding, i);
    gpointer data = NULL;
    gsize size;

    if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
        == 0)
      continue;

    /* Encryption not supported yet */
    if (enc->type != 0)
      return GST_FLOW_ERROR;

    if (i + 1 >= encodings->len)
      return GST_FLOW_ERROR;

    if (enc->comp_settings_length == 0)
      continue;

    data = enc->comp_settings;
    size = enc->comp_settings_length;

    if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
      return GST_FLOW_ERROR;

    g_free (enc->comp_settings);

    enc->comp_settings = data;
    enc->comp_settings_length = size;
  }

  return GST_FLOW_OK;
}

gboolean
gst_matroska_decode_data (GArray * encodings, gpointer * data_out,
    gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
{
  gpointer data;
  gsize size;
  gboolean ret = TRUE;
  gint i;

  g_return_val_if_fail (encodings != NULL, FALSE);
  g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
  g_return_val_if_fail (size_out != NULL, FALSE);

  data = *data_out;
  size = *size_out;

  for (i = 0; i < encodings->len; i++) {
    GstMatroskaTrackEncoding *enc =
        &g_array_index (encodings, GstMatroskaTrackEncoding, i);
    gpointer new_data = NULL;
    gsize new_size = 0;

    if ((enc->scope & scope) == 0)
      continue;

    /* Encryption not supported yet */
    if (enc->type != 0) {
      ret = FALSE;
      break;
    }

    new_data = data;
    new_size = size;

    ret =
        gst_matroska_decompress_data (enc, &new_data, &new_size,
        enc->comp_algo);

    if (!ret)
      break;

    if ((data == *data_out && free) || (data != *data_out))
      g_free (data);

    data = new_data;
    size = new_size;
  }

  if (!ret) {
    if ((data == *data_out && free) || (data != *data_out))
      g_free (data);

    *data_out = NULL;
    *size_out = 0;
  } else {
    *data_out = data;
    *size_out = size;
  }

  return ret;
}

static gint
gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
{
  if (i1->time < i2->time)
    return -1;
  else if (i1->time > i2->time)
    return 1;
  else if (i1->block < i2->block)
    return -1;
  else if (i1->block > i2->block)
    return 1;
  else
    return 0;
}

gint
gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
    gpointer user_data)
{
  if (i1->time < *time)
    return -1;
  else if (i1->time > *time)
    return 1;
  else
    return 0;
}

GstMatroskaIndex *
gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
    GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
    gint * _entry_index, GstSearchMode snap_dir)
{
  GstMatroskaIndex *entry = NULL;
  GArray *index;

  /* find entry just before or at the requested position */
  if (track && track->index_table)
    index = track->index_table;
  else
    index = common->index;

  if (!index || !index->len)
    return NULL;

  entry =
      gst_util_array_binary_search (index->data, index->len,
      sizeof (GstMatroskaIndex),
      (GCompareDataFunc) gst_matroska_index_seek_find, snap_dir, &seek_pos,
      NULL);

  if (entry == NULL) {
    if (snap_dir == GST_SEARCH_MODE_AFTER) {
      /* Can only happen with a reverse seek past the end */
      entry = &g_array_index (index, GstMatroskaIndex, index->len - 1);
    } else {
      /* Can only happen with a forward seek before the start */
      entry = &g_array_index (index, GstMatroskaIndex, 0);
    }
  }

  if (_index)
    *_index = index;
  if (_entry_index)
    *_entry_index = entry - (GstMatroskaIndex *) index->data;

  return entry;
}

static gint
gst_matroska_read_common_encoding_cmp (GstMatroskaTrackEncoding * a,
    GstMatroskaTrackEncoding * b)
{
  if (b->order > a->order)
    return 1;
  else if (b->order < a->order)
    return -1;
  else
    return 0;
}

static gboolean
gst_matroska_read_common_encoding_order_unique (GArray * encodings, guint64
    order)
{
  gint i;

  if (encodings == NULL || encodings->len == 0)
    return TRUE;

  for (i = 0; i < encodings->len; i++)
    if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
      return FALSE;

  return TRUE;
}

/* takes ownership of taglist */
void
gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common,
    GstElement * el, GstTagList * taglist)
{
  if (common->global_tags) {
    gst_tag_list_insert (common->global_tags, taglist, GST_TAG_MERGE_APPEND);
    gst_tag_list_unref (taglist);
  } else {
    common->global_tags = taglist;
  }
  common->global_tags_changed = TRUE;
}

gint64
gst_matroska_read_common_get_length (GstMatroskaReadCommon * common)
{
  gint64 end = -1;

  if (!gst_pad_peer_query_duration (common->sinkpad, GST_FORMAT_BYTES,
          &end) || end < 0)
    GST_DEBUG_OBJECT (common->sinkpad, "no upstream length");

  return end;
}

/* determine track to seek in */
GstMatroskaTrackContext *
gst_matroska_read_common_get_seek_track (GstMatroskaReadCommon * common,
    GstMatroskaTrackContext * track)
{
  gint i;

  if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
    return track;

  for (i = 0; i < common->src->len; i++) {
    GstMatroskaTrackContext *stream;

    stream = g_ptr_array_index (common->src, i);
    if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
      track = stream;
  }

  return track;
}

/* skip unknown or alike element */
GstFlowReturn
gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, const gchar * parent_name, guint id)
{
  if (id == GST_EBML_ID_VOID) {
    GST_DEBUG_OBJECT (common->sinkpad, "Skipping EBML Void element");
  } else if (id == GST_EBML_ID_CRC32) {
    GST_DEBUG_OBJECT (common->sinkpad, "Skipping EBML CRC32 element");
  } else {
    GST_WARNING_OBJECT (common->sinkpad,
        "Unknown %s subelement 0x%x - ignoring", parent_name, id);
  }

  return gst_ebml_read_skip (ebml);
}

static GstFlowReturn
gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, GstTagList * taglist)
{
  guint32 id;
  GstFlowReturn ret;
  gchar *description = NULL;
  gchar *filename = NULL;
  gchar *mimetype = NULL;
  guint8 *data = NULL;
  guint64 datalen = 0;

  DEBUG_ELEMENT_START (common, ebml, "AttachedFile");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    /* read all sub-entries */

    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_FILEDESCRIPTION:
        if (description) {
          GST_WARNING_OBJECT (common->sinkpad,
              "FileDescription can only appear once");
          break;
        }

        ret = gst_ebml_read_utf8 (ebml, &id, &description);
        GST_DEBUG_OBJECT (common->sinkpad, "FileDescription: %s",
            GST_STR_NULL (description));
        break;
      case GST_MATROSKA_ID_FILENAME:
        if (filename) {
          GST_WARNING_OBJECT (common->sinkpad, "FileName can only appear once");
          break;
        }

        ret = gst_ebml_read_utf8 (ebml, &id, &filename);

        GST_DEBUG_OBJECT (common->sinkpad, "FileName: %s",
            GST_STR_NULL (filename));
        break;
      case GST_MATROSKA_ID_FILEMIMETYPE:
        if (mimetype) {
          GST_WARNING_OBJECT (common->sinkpad,
              "FileMimeType can only appear once");
          break;
        }

        ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
        GST_DEBUG_OBJECT (common->sinkpad, "FileMimeType: %s",
            GST_STR_NULL (mimetype));
        break;
      case GST_MATROSKA_ID_FILEDATA:
        if (data) {
          GST_WARNING_OBJECT (common->sinkpad, "FileData can only appear once");
          break;
        }

        ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
        GST_DEBUG_OBJECT (common->sinkpad,
            "FileData of size %" G_GUINT64_FORMAT, datalen);
        break;

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml,
            "AttachedFile", id);
        break;
      case GST_MATROSKA_ID_FILEUID:
        ret = gst_ebml_read_skip (ebml);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);

  if (filename && mimetype && data && datalen > 0) {
    GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
    GstBuffer *tagbuffer = NULL;
    GstSample *tagsample = NULL;
    GstStructure *info = NULL;
    GstCaps *caps = NULL;
    gchar *filename_lc = g_utf8_strdown (filename, -1);

    GST_DEBUG_OBJECT (common->sinkpad, "Creating tag for attachment with "
        "filename '%s', mimetype '%s', description '%s', "
        "size %" G_GUINT64_FORMAT, filename, mimetype,
        GST_STR_NULL (description), datalen);

    /* TODO: better heuristics for different image types */
    if (strstr (filename_lc, "cover")) {
      if (strstr (filename_lc, "back"))
        image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
      else
        image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
    } else if (g_str_has_prefix (mimetype, "image/") ||
        g_str_has_suffix (filename_lc, "png") ||
        g_str_has_suffix (filename_lc, "jpg") ||
        g_str_has_suffix (filename_lc, "jpeg") ||
        g_str_has_suffix (filename_lc, "gif") ||
        g_str_has_suffix (filename_lc, "bmp")) {
      image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
    }
    g_free (filename_lc);

    /* First try to create an image tag buffer from this */
    if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
      tagsample =
          gst_tag_image_data_to_image_sample (data, datalen, image_type);

      if (!tagsample)
        image_type = GST_TAG_IMAGE_TYPE_NONE;
      else {
        data = NULL;
        tagbuffer = gst_buffer_ref (gst_sample_get_buffer (tagsample));
        caps = gst_caps_ref (gst_sample_get_caps (tagsample));
        info = gst_structure_copy (gst_sample_get_info (tagsample));
        gst_sample_unref (tagsample);
      }
    }

    /* if this failed create an attachment buffer */
    if (!tagbuffer) {
      tagbuffer = gst_buffer_new_wrapped (g_memdup (data, datalen), datalen);

      caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
      if (caps == NULL)
        caps = gst_caps_new_empty_simple (mimetype);
    }

    /* Set filename and description in the info */
    if (info == NULL)
      info = gst_structure_new_empty ("GstTagImageInfo");

    gst_structure_set (info, "filename", G_TYPE_STRING, filename, NULL);
    if (description)
      gst_structure_set (info, "description", G_TYPE_STRING, description, NULL);

    tagsample = gst_sample_new (tagbuffer, caps, NULL, info);

    gst_buffer_unref (tagbuffer);
    gst_caps_unref (caps);

    GST_DEBUG_OBJECT (common->sinkpad,
        "Created attachment sample: %" GST_PTR_FORMAT, tagsample);

    /* and append to the tag list */
    if (image_type != GST_TAG_IMAGE_TYPE_NONE)
      gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagsample,
          NULL);
    else
      gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
          tagsample, NULL);

    /* the list adds it own ref */
    gst_sample_unref (tagsample);
  }

  g_free (filename);
  g_free (mimetype);
  g_free (data);
  g_free (description);

  return ret;
}

GstFlowReturn
gst_matroska_read_common_parse_attachments (GstMatroskaReadCommon * common,
    GstElement * el, GstEbmlRead * ebml)
{
  guint32 id;
  GstFlowReturn ret = GST_FLOW_OK;
  GstTagList *taglist;

  DEBUG_ELEMENT_START (common, ebml, "Attachments");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
    return ret;
  }

  taglist = gst_tag_list_new_empty ();
  gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_ATTACHEDFILE:
        ret = gst_matroska_read_common_parse_attached_file (common, ebml,
            taglist);
        break;

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml,
            "Attachments", id);
        break;
    }
  }
  DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);

  if (gst_tag_list_n_tags (taglist) > 0) {
    GST_DEBUG_OBJECT (common->sinkpad, "Storing attachment tags");
    gst_matroska_read_common_found_global_tag (common, el, taglist);
  } else {
    GST_DEBUG_OBJECT (common->sinkpad, "No valid attachments found");
    gst_tag_list_unref (taglist);
  }

  common->attachments_parsed = TRUE;

  return ret;
}

static void
gst_matroska_read_common_parse_toc_tag (GstTocEntry * entry,
    GArray * edition_targets, GArray * chapter_targtes, GstTagList * tags)
{
  gchar *uid;
  guint i;
  guint64 tgt;
  GArray *targets;
  GList *cur;
  GstTagList *etags;

  targets =
      (gst_toc_entry_get_entry_type (entry) ==
      GST_TOC_ENTRY_TYPE_EDITION) ? edition_targets : chapter_targtes;

  etags = gst_tag_list_new_empty ();

  for (i = 0; i < targets->len; ++i) {
    tgt = g_array_index (targets, guint64, i);

    if (tgt == 0)
      gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND);
    else {
      uid = g_strdup_printf ("%" G_GUINT64_FORMAT, tgt);
      if (g_strcmp0 (gst_toc_entry_get_uid (entry), uid) == 0)
        gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND);
      g_free (uid);
    }
  }

  gst_toc_entry_merge_tags (entry, etags, GST_TAG_MERGE_APPEND);
  gst_tag_list_unref (etags);

  cur = gst_toc_entry_get_sub_entries (entry);
  while (cur != NULL) {
    gst_matroska_read_common_parse_toc_tag (cur->data, edition_targets,
        chapter_targtes, tags);
    cur = cur->next;
  }
}

static GstFlowReturn
gst_matroska_read_common_parse_metadata_targets (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, GArray * edition_targets, GArray * chapter_targets,
    GArray * track_targets, guint64 * target_type_value, gchar ** target_type)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint32 id;
  guint64 uid;
  guint64 tmp;
  gchar *str;

  DEBUG_ELEMENT_START (common, ebml, "TagTargets");

  *target_type_value = 50;
  *target_type = NULL;

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_TARGETCHAPTERUID:
        if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
          g_array_append_val (chapter_targets, uid);
        break;

      case GST_MATROSKA_ID_TARGETEDITIONUID:
        if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
          g_array_append_val (edition_targets, uid);
        break;

      case GST_MATROSKA_ID_TARGETTRACKUID:
        if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
          g_array_append_val (track_targets, uid);
        break;

      case GST_MATROSKA_ID_TARGETTYPEVALUE:
        if ((ret = gst_ebml_read_uint (ebml, &id, &tmp)) == GST_FLOW_OK)
          *target_type_value = tmp;
        break;

      case GST_MATROSKA_ID_TARGETTYPE:
        if ((ret = gst_ebml_read_ascii (ebml, &id, &str)) == GST_FLOW_OK) {
          g_free (*target_type);
          *target_type = str;
        }
        break;

      default:
        ret =
            gst_matroska_read_common_parse_skip (common, ebml, "TagTargets",
            id);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);

  return ret;
}

static void
gst_matroska_read_common_postprocess_toc_entries (GList * toc_entries,
    guint64 max, const gchar * parent_uid)
{
  GstTocEntry *cur_info, *prev_info, *next_info;
  GList *cur_list, *prev_list, *next_list;
  gint64 cur_start, prev_start, stop;

  cur_list = toc_entries;
  while (cur_list != NULL) {
    cur_info = cur_list->data;

    switch (gst_toc_entry_get_entry_type (cur_info)) {
      case GST_TOC_ENTRY_TYPE_ANGLE:
      case GST_TOC_ENTRY_TYPE_VERSION:
      case GST_TOC_ENTRY_TYPE_EDITION:
        /* in Matroska terms edition has duration of full track */
        gst_toc_entry_set_start_stop_times (cur_info, 0, max);

        gst_matroska_read_common_postprocess_toc_entries
            (gst_toc_entry_get_sub_entries (cur_info), max,
            gst_toc_entry_get_uid (cur_info));
        break;

      case GST_TOC_ENTRY_TYPE_TITLE:
      case GST_TOC_ENTRY_TYPE_TRACK:
      case GST_TOC_ENTRY_TYPE_CHAPTER:
        prev_list = cur_list->prev;
        next_list = cur_list->next;

        if (prev_list != NULL)
          prev_info = prev_list->data;
        else
          prev_info = NULL;

        if (next_list != NULL)
          next_info = next_list->data;
        else
          next_info = NULL;

        /* updated stop time in previous chapter and it's subchapters */
        if (prev_info != NULL) {
          gst_toc_entry_get_start_stop_times (prev_info, &prev_start, &stop);
          gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop);

          stop = cur_start;
          gst_toc_entry_set_start_stop_times (prev_info, prev_start, stop);

          gst_matroska_read_common_postprocess_toc_entries
              (gst_toc_entry_get_sub_entries (prev_info), cur_start,
              gst_toc_entry_get_uid (prev_info));
        }

        /* updated stop time in current chapter and it's subchapters */
        if (next_info == NULL) {
          gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop);

          if (stop == -1) {
            stop = max;
            gst_toc_entry_set_start_stop_times (cur_info, cur_start, stop);
          }

          gst_matroska_read_common_postprocess_toc_entries
              (gst_toc_entry_get_sub_entries (cur_info), stop,
              gst_toc_entry_get_uid (cur_info));
        }
        break;
      case GST_TOC_ENTRY_TYPE_INVALID:
        break;
    }
    cur_list = cur_list->next;
  }
}

static GstFlowReturn
gst_matroska_read_common_parse_chapter_titles (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, GstTagList * titles)
{
  guint32 id;
  gchar *title = NULL;
  GstFlowReturn ret = GST_FLOW_OK;

  DEBUG_ELEMENT_START (common, ebml, "ChaptersTitles");


  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_CHAPSTRING:
        ret = gst_ebml_read_utf8 (ebml, &id, &title);
        break;

      default:
        ret =
            gst_matroska_read_common_parse_skip (common, ebml, "ChaptersTitles",
            id);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);

  if (title != NULL && ret == GST_FLOW_OK)
    gst_tag_list_add (titles, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, title, NULL);

  g_free (title);
  return ret;
}

static GstFlowReturn
gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, GList ** subentries)
{
  guint32 id;
  guint64 start_time = -1, stop_time = -1;
  guint64 is_hidden = 0, is_enabled = 1, uid = 0;
  GstFlowReturn ret = GST_FLOW_OK;
  GstTocEntry *chapter_info;
  GstTagList *tags;
  gchar *uid_str;
  GList *subsubentries = NULL, *l;

  DEBUG_ELEMENT_START (common, ebml, "ChaptersElement");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
    return ret;
  }

  tags = gst_tag_list_new_empty ();

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_CHAPTERUID:
        ret = gst_ebml_read_uint (ebml, &id, &uid);
        break;

      case GST_MATROSKA_ID_CHAPTERTIMESTART:
        ret = gst_ebml_read_uint (ebml, &id, &start_time);
        break;

      case GST_MATROSKA_ID_CHAPTERTIMESTOP:
        ret = gst_ebml_read_uint (ebml, &id, &stop_time);
        break;

      case GST_MATROSKA_ID_CHAPTERATOM:
        ret =
            gst_matroska_read_common_parse_chapter_element (common, ebml,
            &subsubentries);
        break;

      case GST_MATROSKA_ID_CHAPTERDISPLAY:
        ret =
            gst_matroska_read_common_parse_chapter_titles (common, ebml, tags);
        break;

      case GST_MATROSKA_ID_CHAPTERFLAGHIDDEN:
        ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
        break;

      case GST_MATROSKA_ID_CHAPTERFLAGENABLED:
        ret = gst_ebml_read_uint (ebml, &id, &is_enabled);
        break;

      default:
        ret =
            gst_matroska_read_common_parse_skip (common, ebml,
            "ChaptersElement", id);
        break;
    }
  }

  if (uid == 0)
    uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
  uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
  chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid_str);
  g_free (uid_str);

  gst_toc_entry_set_tags (chapter_info, tags);
  gst_toc_entry_set_start_stop_times (chapter_info, start_time, stop_time);

  for (l = subsubentries; l; l = l->next)
    gst_toc_entry_append_sub_entry (chapter_info, l->data);
  g_list_free (subsubentries);

  DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);

  /* start time is mandatory and has no default value,
   * so we should skip chapters without it */
  if (is_hidden == 0 && is_enabled > 0 &&
      start_time != -1 && ret == GST_FLOW_OK) {
    *subentries = g_list_append (*subentries, chapter_info);
  } else
    gst_toc_entry_unref (chapter_info);

  return ret;
}

static GstFlowReturn
gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, GstToc * toc)
{
  guint32 id;
  guint64 is_hidden = 0, uid = 0;
  GstFlowReturn ret = GST_FLOW_OK;
  GstTocEntry *edition_info;
  GList *subentries = NULL, *l;
  gchar *uid_str;

  DEBUG_ELEMENT_START (common, ebml, "ChaptersEdition");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_EDITIONUID:
        ret = gst_ebml_read_uint (ebml, &id, &uid);
        break;

      case GST_MATROSKA_ID_CHAPTERATOM:
        ret =
            gst_matroska_read_common_parse_chapter_element (common, ebml,
            &subentries);
        break;

      case GST_MATROSKA_ID_EDITIONFLAGHIDDEN:
        ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
        break;

      default:
        ret =
            gst_matroska_read_common_parse_skip (common, ebml,
            "ChaptersEdition", id);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);

  if (uid == 0)
    uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
  uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
  edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, uid_str);
  gst_toc_entry_set_start_stop_times (edition_info, -1, -1);
  g_free (uid_str);

  for (l = subentries; l; l = l->next)
    gst_toc_entry_append_sub_entry (edition_info, l->data);
  g_list_free (subentries);

  if (is_hidden == 0 && subentries != NULL && ret == GST_FLOW_OK)
    gst_toc_append_entry (toc, edition_info);
  else {
    GST_DEBUG_OBJECT (common->sinkpad,
        "Skipping empty or hidden edition in the chapters TOC");
    gst_toc_entry_unref (edition_info);
  }

  return ret;
}

GstFlowReturn
gst_matroska_read_common_parse_chapters (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml)
{
  guint32 id;
  GstFlowReturn ret = GST_FLOW_OK;
  GstToc *toc;

  DEBUG_ELEMENT_START (common, ebml, "Chapters");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
    return ret;
  }

  /* FIXME: create CURRENT toc as well */
  toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_EDITIONENTRY:
        ret =
            gst_matroska_read_common_parse_chapter_edition (common, ebml, toc);
        break;

      default:
        ret =
            gst_matroska_read_common_parse_skip (common, ebml, "Chapters", id);
        break;
    }
  }

  if (gst_toc_get_entries (toc) != NULL) {
    gst_matroska_read_common_postprocess_toc_entries (gst_toc_get_entries (toc),
        common->segment.duration, "");

    common->toc = toc;
  } else
    gst_toc_unref (toc);

  common->chapters_parsed = TRUE;

  DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
  return ret;
}

GstFlowReturn
gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml)
{
  GstFlowReturn ret;
  gchar *doctype;
  guint version;
  guint32 id;

  /* this function is the first to be called */

  /* default init */
  doctype = NULL;
  version = 1;

  ret = gst_ebml_peek_id (ebml, &id);
  if (ret != GST_FLOW_OK)
    return ret;

  GST_DEBUG_OBJECT (common->sinkpad, "id: %08x", id);

  if (id != GST_EBML_ID_HEADER) {
    GST_ERROR_OBJECT (common->sinkpad, "Failed to read header");
    goto exit;
  }

  ret = gst_ebml_read_master (ebml, &id);
  if (ret != GST_FLOW_OK)
    return ret;

  while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    ret = gst_ebml_peek_id (ebml, &id);
    if (ret != GST_FLOW_OK)
      goto exit_error;

    switch (id) {
        /* is our read version uptodate? */
      case GST_EBML_ID_EBMLREADVERSION:{
        guint64 num;

        ret = gst_ebml_read_uint (ebml, &id, &num);
        if (ret != GST_FLOW_OK)
          goto exit_error;
        if (num != GST_EBML_VERSION) {
          GST_ERROR_OBJECT (common->sinkpad,
              "Unsupported EBML version %" G_GUINT64_FORMAT, num);
          goto exit_error;
        }

        GST_DEBUG_OBJECT (common->sinkpad,
            "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
        break;
      }

        /* we only handle 8 byte lengths at max */
      case GST_EBML_ID_EBMLMAXSIZELENGTH:{
        guint64 num;

        ret = gst_ebml_read_uint (ebml, &id, &num);
        if (ret != GST_FLOW_OK)
          goto exit_error;
        if (num > sizeof (guint64)) {
          GST_ERROR_OBJECT (common->sinkpad,
              "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
          return GST_FLOW_ERROR;
        }
        GST_DEBUG_OBJECT (common->sinkpad,
            "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
        break;
      }

        /* we handle 4 byte IDs at max */
      case GST_EBML_ID_EBMLMAXIDLENGTH:{
        guint64 num;

        ret = gst_ebml_read_uint (ebml, &id, &num);
        if (ret != GST_FLOW_OK)
          goto exit_error;
        if (num > sizeof (guint32)) {
          GST_ERROR_OBJECT (common->sinkpad,
              "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
          return GST_FLOW_ERROR;
        }
        GST_DEBUG_OBJECT (common->sinkpad,
            "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
        break;
      }

      case GST_EBML_ID_DOCTYPE:{
        gchar *text;

        ret = gst_ebml_read_ascii (ebml, &id, &text);
        if (ret != GST_FLOW_OK)
          goto exit_error;

        GST_DEBUG_OBJECT (common->sinkpad, "EbmlDocType: %s",
            GST_STR_NULL (text));

        g_free (doctype);
        doctype = text;
        break;
      }

      case GST_EBML_ID_DOCTYPEREADVERSION:{
        guint64 num;

        ret = gst_ebml_read_uint (ebml, &id, &num);
        if (ret != GST_FLOW_OK)
          goto exit_error;
        version = num;
        GST_DEBUG_OBJECT (common->sinkpad,
            "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
        break;
      }

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml,
            "EBML header", id);
        if (ret != GST_FLOW_OK)
          goto exit_error;
        break;

        /* we ignore these two, as they don't tell us anything we care about */
      case GST_EBML_ID_EBMLVERSION:
      case GST_EBML_ID_DOCTYPEVERSION:
        ret = gst_ebml_read_skip (ebml);
        if (ret != GST_FLOW_OK)
          goto exit_error;
        break;
    }
  }

exit:

  if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
      (doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
      (doctype == NULL)) {
    if (version <= 2) {
      if (doctype) {
        GST_INFO_OBJECT (common->sinkpad, "Input is %s version %d", doctype,
            version);
        if (!strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM))
          common->is_webm = TRUE;
      } else {
        GST_WARNING_OBJECT (common->sinkpad,
            "Input is EBML without doctype, assuming " "matroska (version %d)",
            version);
      }
      ret = GST_FLOW_OK;
    } else {
      GST_ELEMENT_ERROR (common, STREAM, DEMUX, (NULL),
          ("Demuxer version (2) is too old to read %s version %d",
              GST_STR_NULL (doctype), version));
      ret = GST_FLOW_ERROR;
    }
  } else {
    GST_ELEMENT_ERROR (common, STREAM, WRONG_TYPE, (NULL),
        ("Input is not a matroska stream (doctype=%s)", doctype));
    ret = GST_FLOW_ERROR;
  }

exit_error:

  g_free (doctype);

  return ret;
}

static GstFlowReturn
gst_matroska_read_common_parse_index_cuetrack (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, guint * nentries)
{
  guint32 id;
  GstFlowReturn ret;
  GstMatroskaIndex idx;

  idx.pos = (guint64) - 1;
  idx.track = 0;
  idx.time = GST_CLOCK_TIME_NONE;
  idx.block = 1;

  DEBUG_ELEMENT_START (common, ebml, "CueTrackPositions");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
        /* track number */
      case GST_MATROSKA_ID_CUETRACK:
      {
        guint64 num;

        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
          break;

        if (num == 0) {
          idx.track = 0;
          GST_WARNING_OBJECT (common->sinkpad, "Invalid CueTrack 0");
          break;
        }

        GST_DEBUG_OBJECT (common->sinkpad, "CueTrack: %" G_GUINT64_FORMAT, num);
        idx.track = num;
        break;
      }

        /* position in file */
      case GST_MATROSKA_ID_CUECLUSTERPOSITION:
      {
        guint64 num;

        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
          break;

        if (num > G_MAXINT64) {
          GST_WARNING_OBJECT (common->sinkpad,
              "CueClusterPosition %" G_GUINT64_FORMAT " too large", num);
          break;
        }

        idx.pos = num;
        break;
      }

        /* number of block in the cluster */
      case GST_MATROSKA_ID_CUEBLOCKNUMBER:
      {
        guint64 num;

        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
          break;

        if (num == 0) {
          GST_WARNING_OBJECT (common->sinkpad, "Invalid CueBlockNumber 0");
          break;
        }

        GST_DEBUG_OBJECT (common->sinkpad, "CueBlockNumber: %" G_GUINT64_FORMAT,
            num);
        idx.block = num;

        /* mild sanity check, disregard strange cases ... */
        if (idx.block > G_MAXUINT16) {
          GST_DEBUG_OBJECT (common->sinkpad, "... looks suspicious, ignoring");
          idx.block = 1;
        }
        break;
      }

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml,
            "CueTrackPositions", id);
        break;

      case GST_MATROSKA_ID_CUECODECSTATE:
      case GST_MATROSKA_ID_CUEREFERENCE:
        ret = gst_ebml_read_skip (ebml);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);

  /* (e.g.) lavf typically creates entries without a block number,
   * which is bogus and leads to contradictory information */
  if (common->index->len) {
    GstMatroskaIndex *last_idx;

    last_idx = &g_array_index (common->index, GstMatroskaIndex,
        common->index->len - 1);
    if (last_idx->block == idx.block && last_idx->pos == idx.pos &&
        last_idx->track == idx.track && idx.time > last_idx->time) {
      GST_DEBUG_OBJECT (common->sinkpad, "Cue entry refers to same location, "
          "but has different time than previous entry; discarding");
      idx.track = 0;
    }
  }

  if ((ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
      && idx.pos != (guint64) - 1 && idx.track > 0) {
    g_array_append_val (common->index, idx);
    (*nentries)++;
  } else if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS) {
    GST_DEBUG_OBJECT (common->sinkpad,
        "CueTrackPositions without valid content");
  }

  return ret;
}

static GstFlowReturn
gst_matroska_read_common_parse_index_pointentry (GstMatroskaReadCommon *
    common, GstEbmlRead * ebml)
{
  guint32 id;
  GstFlowReturn ret;
  GstClockTime time = GST_CLOCK_TIME_NONE;
  guint nentries = 0;

  DEBUG_ELEMENT_START (common, ebml, "CuePoint");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
        /* one single index entry ('point') */
      case GST_MATROSKA_ID_CUETIME:
      {
        if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
          break;

        GST_DEBUG_OBJECT (common->sinkpad, "CueTime: %" G_GUINT64_FORMAT, time);
        time = time * common->time_scale;
        break;
      }

        /* position in the file + track to which it belongs */
      case GST_MATROSKA_ID_CUETRACKPOSITIONS:
      {
        ret = gst_matroska_read_common_parse_index_cuetrack (common, ebml,
            &nentries);
        break;
      }

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml, "CuePoint",
            id);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);

  if (nentries > 0) {
    if (time == GST_CLOCK_TIME_NONE) {
      GST_WARNING_OBJECT (common->sinkpad, "CuePoint without valid time");
      g_array_remove_range (common->index, common->index->len - nentries,
          nentries);
    } else {
      gint i;

      for (i = common->index->len - nentries; i < common->index->len; i++) {
        GstMatroskaIndex *idx =
            &g_array_index (common->index, GstMatroskaIndex, i);

        idx->time = time;
        GST_DEBUG_OBJECT (common->sinkpad, "Index entry: pos=%" G_GUINT64_FORMAT
            ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
            GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
      }
    }
  } else {
    GST_DEBUG_OBJECT (common->sinkpad, "Empty CuePoint");
  }

  return ret;
}

gint
gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common,
    guint track_num)
{
  guint n;

  g_assert (common->src->len == common->num_streams);
  for (n = 0; n < common->src->len; n++) {
    GstMatroskaTrackContext *context = g_ptr_array_index (common->src, n);

    if (context->num == track_num) {
      return n;
    }
  }

  if (n == common->num_streams)
    GST_WARNING_OBJECT (common->sinkpad,
        "Failed to find corresponding pad for tracknum %d", track_num);

  return -1;
}

GstFlowReturn
gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml)
{
  guint32 id;
  GstFlowReturn ret = GST_FLOW_OK;
  guint i;

  if (common->index)
    g_array_free (common->index, TRUE);
  common->index =
      g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);

  DEBUG_ELEMENT_START (common, ebml, "Cues");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
        /* one single index entry ('point') */
      case GST_MATROSKA_ID_POINTENTRY:
        ret = gst_matroska_read_common_parse_index_pointentry (common, ebml);
        break;

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml, "Cues", id);
        break;
    }
  }
  DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);

  /* Sort index by time, smallest time first, for easier searching */
  g_array_sort (common->index, (GCompareFunc) gst_matroska_index_compare);

  /* Now sort the track specific index entries into their own arrays */
  for (i = 0; i < common->index->len; i++) {
    GstMatroskaIndex *idx = &g_array_index (common->index, GstMatroskaIndex,
        i);
    gint track_num;
    GstMatroskaTrackContext *ctx;

#if 0
    if (common->element_index) {
      gint writer_id;

      if (idx->track != 0 &&
          (track_num =
              gst_matroska_read_common_stream_from_num (common,
                  idx->track)) != -1) {
        ctx = g_ptr_array_index (common->src, track_num);

        if (ctx->index_writer_id == -1)
          gst_index_get_writer_id (common->element_index,
              GST_OBJECT (ctx->pad), &ctx->index_writer_id);
        writer_id = ctx->index_writer_id;
      } else {
        if (common->element_index_writer_id == -1)
          gst_index_get_writer_id (common->element_index, GST_OBJECT (common),
              &common->element_index_writer_id);
        writer_id = common->element_index_writer_id;
      }

      GST_LOG_OBJECT (common->sinkpad,
          "adding association %" GST_TIME_FORMAT "-> %" G_GUINT64_FORMAT
          " for writer id %d", GST_TIME_ARGS (idx->time), idx->pos, writer_id);
      gst_index_add_association (common->element_index, writer_id,
          GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
          GST_FORMAT_BYTES, idx->pos + common->ebml_segment_start, NULL);
    }
#endif

    if (idx->track == 0)
      continue;

    track_num = gst_matroska_read_common_stream_from_num (common, idx->track);
    if (track_num == -1)
      continue;

    ctx = g_ptr_array_index (common->src, track_num);

    if (ctx->index_table == NULL)
      ctx->index_table =
          g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);

    g_array_append_vals (ctx->index_table, idx, 1);
  }

  common->index_parsed = TRUE;

  /* sanity check; empty index normalizes to no index */
  if (common->index->len == 0) {
    g_array_free (common->index, TRUE);
    common->index = NULL;
  }

  return ret;
}

GstFlowReturn
gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common,
    GstElement * el, GstEbmlRead * ebml)
{
  GstFlowReturn ret = GST_FLOW_OK;
  gdouble dur_f = -1.0;
  guint32 id;

  DEBUG_ELEMENT_START (common, ebml, "SegmentInfo");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
        /* cluster timecode */
      case GST_MATROSKA_ID_TIMECODESCALE:{
        guint64 num;

        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
          break;


        GST_DEBUG_OBJECT (common->sinkpad, "TimeCodeScale: %" G_GUINT64_FORMAT,
            num);
        common->time_scale = num;
        break;
      }

      case GST_MATROSKA_ID_DURATION:{
        if ((ret = gst_ebml_read_float (ebml, &id, &dur_f)) != GST_FLOW_OK)
          break;

        if (dur_f <= 0.0) {
          GST_WARNING_OBJECT (common->sinkpad, "Invalid duration %lf", dur_f);
          break;
        }

        GST_DEBUG_OBJECT (common->sinkpad, "Duration: %lf", dur_f);
        break;
      }

      case GST_MATROSKA_ID_WRITINGAPP:{
        gchar *text;

        if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
          break;

        GST_DEBUG_OBJECT (common->sinkpad, "WritingApp: %s",
            GST_STR_NULL (text));
        common->writing_app = text;
        break;
      }

      case GST_MATROSKA_ID_MUXINGAPP:{
        gchar *text;

        if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
          break;

        GST_DEBUG_OBJECT (common->sinkpad, "MuxingApp: %s",
            GST_STR_NULL (text));
        common->muxing_app = text;
        break;
      }

      case GST_MATROSKA_ID_DATEUTC:{
        gint64 time;

        if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
          break;

        GST_DEBUG_OBJECT (common->sinkpad, "DateUTC: %" G_GINT64_FORMAT, time);
        common->created = time;
        break;
      }

      case GST_MATROSKA_ID_TITLE:{
        gchar *text;
        GstTagList *taglist;

        if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
          break;

        GST_DEBUG_OBJECT (common->sinkpad, "Title: %s", GST_STR_NULL (text));
        taglist = gst_tag_list_new (GST_TAG_TITLE, text, NULL);
        gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
        gst_matroska_read_common_found_global_tag (common, el, taglist);
        g_free (text);
        break;
      }

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml,
            "SegmentInfo", id);
        break;

        /* fall through */
      case GST_MATROSKA_ID_SEGMENTUID:
      case GST_MATROSKA_ID_SEGMENTFILENAME:
      case GST_MATROSKA_ID_PREVUID:
      case GST_MATROSKA_ID_PREVFILENAME:
      case GST_MATROSKA_ID_NEXTUID:
      case GST_MATROSKA_ID_NEXTFILENAME:
      case GST_MATROSKA_ID_SEGMENTFAMILY:
      case GST_MATROSKA_ID_CHAPTERTRANSLATE:
        ret = gst_ebml_read_skip (ebml);
        break;
    }
  }

  if (dur_f > 0.0) {
    GstClockTime dur_u;

    dur_u = gst_gdouble_to_guint64 (dur_f *
        gst_guint64_to_gdouble (common->time_scale));
    if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64)
      common->segment.duration = dur_u;
  }

  DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);

  common->segmentinfo_parsed = TRUE;

  return ret;
}

static GstFlowReturn
gst_matroska_read_common_parse_metadata_id_simple_tag (GstMatroskaReadCommon *
    common, GstEbmlRead * ebml, GstTagList ** p_taglist, gchar * parent)
{
  /* FIXME: check if there are more useful mappings */
  static const struct
  {
    const gchar *matroska_tagname;
    const gchar *gstreamer_tagname;
  }
  tag_conv[] = {
    {
      /* The following list has the _same_ order as the one in Matroska spec. Please, don't mess it up. */
      /* TODO: Nesting information:
         ORIGINAL A special tag that is meant to have other tags inside (using nested tags) to describe the original work of art that this item is based on. All tags in this list can be used "under" the ORIGINAL tag like LYRICIST, PERFORMER, etc.
         SAMPLE A tag that contains other tags to describe a sample used in the targeted item taken from another work of art. All tags in this list can be used "under" the SAMPLE tag like TITLE, ARTIST, DATE_RELEASED, etc.
         COUNTRY The name of the country (biblio ISO-639-2) that is meant to have other tags inside (using nested tags) to country specific information about the item. All tags in this list can be used "under" the COUNTRY_SPECIFIC tag like LABEL, PUBLISH_RATING, etc.
       */

      /* Organizational Information */
    GST_MATROSKA_TAG_ID_TOTAL_PARTS, GST_TAG_TRACK_COUNT}, {
    GST_MATROSKA_TAG_ID_PART_NUMBER, GST_TAG_TRACK_NUMBER}, {
      /* TODO: PART_OFFSET A number to add to PART_NUMBER when the parts at that level don't start at 1. (e.g. if TargetType is TRACK, the track number of the second audio CD) */

      /* Titles */
    GST_MATROSKA_TAG_ID_SUBTITLE, GST_TAG_TITLE}, {     /* Sub Title of the entity. Since we're concat'ing all title-like entities anyway, might as well add the sub-title. */
    GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
    GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {        /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */

      /* TODO: Nested Information:
         URL URL corresponding to the tag it's included in.
         SORT_WITH A child element to indicate what alternative value the parent tag can have to be sorted, for example "Pet Shop Boys" instead of "The Pet Shop Boys". Or "Marley Bob" and "Marley Ziggy" (no comma needed).
         INSTRUMENTS The instruments that are being used/played, separated by a comma. It should be a child of the following tags: ARTIST, LEAD_PERFORMER or ACCOMPANIMENT.
         EMAIL Email corresponding to the tag it's included in.
         ADDRESS The physical address of the entity. The address should include a country code. It can be useful for a recording label.
         FAX The fax number corresponding to the tag it's included in. It can be useful for a recording label.
         PHONE The phone number corresponding to the tag it's included in. It can be useful for a recording label.
       */

      /* Entities */
    GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
    GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
    GST_MATROSKA_TAG_ID_ACCOMPANIMENT, GST_TAG_PERFORMER}, {    /* Band/orchestra/accompaniment/musician. This is akin to the TPE2 tag in ID3. */
    GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
      /* ARRANGER The person who arranged the piece, e.g., Ravel. */
    GST_MATROSKA_TAG_ID_LYRICS, GST_TAG_LYRICS}, {      /* The lyrics corresponding to a song (in case audio synchronization is not known or as a doublon to a subtitle track). Editing this value when subtitles are found should also result in editing the subtitle track for more consistency. */
      /* LYRICIST The person who wrote the lyrics for a musical item. This is akin to the TEXT tag in ID3. */
    GST_MATROSKA_TAG_ID_CONDUCTOR, GST_TAG_PERFORMER}, {        /* Conductor/performer refinement. This is akin to the TPE3 tag in ID3. */
      /* DIRECTOR This is akin to the IART tag in RIFF. */
    GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
      /* ASSISTANT_DIRECTOR The name of the assistant director. */
      /* DIRECTOR_OF_PHOTOGRAPHY The name of the director of photography, also known as cinematographer. This is akin to the ICNM tag in Extended RIFF. */
      /* SOUND_ENGINEER The name of the sound engineer or sound recordist. */
      /* ART_DIRECTOR The person who oversees the artists and craftspeople who build the sets. */
      /* PRODUCTION_DESIGNER Artist responsible for designing the overall visual appearance of a movie. */
      /* CHOREGRAPHER The name of the choregrapher */
      /* COSTUME_DESIGNER The name of the costume designer */
      /* ACTOR An actor or actress playing a role in this movie. This is the person's real name, not the character's name the person is playing. */
      /* CHARACTER The name of the character an actor or actress plays in this movie. This should be a sub-tag of an ACTOR tag in order not to cause ambiguities. */
      /* WRITTEN_BY The author of the story or script (used for movies and TV shows). */
      /* SCREENPLAY_BY The author of the screenplay or scenario (used for movies and TV shows). */
      /* EDITED_BY This is akin to the IEDT tag in Extended RIFF. */
      /* PRODUCER Produced by. This is akin to the IPRO tag in Extended RIFF. */
      /* COPRODUCER The name of a co-producer. */
      /* EXECUTIVE_PRODUCER The name of an executive producer. */
      /* DISTRIBUTED_BY This is akin to the IDST tag in Extended RIFF. */
      /* MASTERED_BY The engineer who mastered the content for a physical medium or for digital distribution. */
    GST_MATROSKA_TAG_ID_ENCODED_BY, GST_TAG_ENCODED_BY}, {      /* This is akin to the TENC tag in ID3. */
      /* MIXED_BY DJ mix by the artist specified */
      /* REMIXED_BY Interpreted, remixed, or otherwise modified by. This is akin to the TPE4 tag in ID3. */
      /* PRODUCTION_STUDIO This is akin to the ISTD tag in Extended RIFF. */
      /* THANKS_TO A very general tag for everyone else that wants to be listed. */
      /* PUBLISHER This is akin to the TPUB tag in ID3. */
      /* LABEL The record label or imprint on the disc. */
      /* Search / Classification */
    GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}, {
      /* MOOD Intended to reflect the mood of the item with a few keywords, e.g. "Romantic", "Sad" or "Uplifting". The format follows that of the TMOO tag in ID3. */
      /* ORIGINAL_MEDIA_TYPE Describes the original type of the media, such as, "DVD", "CD", "computer image," "drawing," "lithograph," and so forth. This is akin to the TMED tag in ID3. */
      /* CONTENT_TYPE The type of the item. e.g. Documentary, Feature Film, Cartoon, Music Video, Music, Sound FX, ... */
      /* SUBJECT Describes the topic of the file, such as "Aerial view of Seattle." */
    GST_MATROSKA_TAG_ID_DESCRIPTION, GST_TAG_DESCRIPTION}, {    /* A short description of the content, such as "Two birds flying." */
    GST_MATROSKA_TAG_ID_KEYWORDS, GST_TAG_KEYWORDS}, {  /* Keywords to the item separated by a comma, used for searching. */
      /* SUMMARY A plot outline or a summary of the story. */
      /* SYNOPSIS A description of the story line of the item. */
      /* INITIAL_KEY The initial key that a musical track starts in. The format is identical to ID3. */
      /* PERIOD Describes the period that the piece is from or about. For example, "Renaissance". */
      /* LAW_RATING Depending on the country it's the format of the rating of a movie (P, R, X in the USA, an age in other countries or a URI defining a logo). */
      /* ICRA The ICRA content rating for parental control. (Previously RSACi) */

      /* Temporal Information */
    GST_MATROSKA_TAG_ID_DATE_RELEASED, GST_TAG_DATE}, { /* The time that the item was originaly released. This is akin to the TDRL tag in ID3. */
    GST_MATROSKA_TAG_ID_DATE_RECORDED, GST_TAG_DATE}, { /* The time that the recording began. This is akin to the TDRC tag in ID3. */
    GST_MATROSKA_TAG_ID_DATE_ENCODED, GST_TAG_DATE}, {  /* The time that the encoding of this item was completed began. This is akin to the TDEN tag in ID3. */
    GST_MATROSKA_TAG_ID_DATE_TAGGED, GST_TAG_DATE}, {   /* The time that the tags were done for this item. This is akin to the TDTG tag in ID3. */
    GST_MATROSKA_TAG_ID_DATE_DIGITIZED, GST_TAG_DATE}, {        /* The time that the item was tranfered to a digital medium. This is akin to the IDIT tag in RIFF. */
    GST_MATROSKA_TAG_ID_DATE_WRITTEN, GST_TAG_DATE}, {  /* The time that the writing of the music/script began. */
    GST_MATROSKA_TAG_ID_DATE_PURCHASED, GST_TAG_DATE}, {        /* Information on when the file was purchased (see also purchase tags). */
    GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {  /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */

      /* Spacial Information */
    GST_MATROSKA_TAG_ID_RECORDING_LOCATION, GST_TAG_GEO_LOCATION_NAME}, {       /* The location where the item was recorded. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. This code is followed by a comma, then more detailed information such as state/province, another comma, and then city. For example, "US, Texas, Austin". This will allow for easy sorting. It is okay to only store the country, or the country and the state/province. More detailed information can be added after the city through the use of additional commas. In cases where the province/state is unknown, but you want to store the city, simply leave a space between the two commas. For example, "US, , Austin". */
      /* COMPOSITION_LOCATION Location that the item was originaly designed/written. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. This code is followed by a comma, then more detailed information such as state/province, another comma, and then city. For example, "US, Texas, Austin". This will allow for easy sorting. It is okay to only store the country, or the country and the state/province. More detailed information can be added after the city through the use of additional commas. In cases where the province/state is unknown, but you want to store the city, simply leave a space between the two commas. For example, "US, , Austin". */
      /* COMPOSER_NATIONALITY Nationality of the main composer of the item, mostly for classical music. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. */

      /* Personal */
    GST_MATROSKA_TAG_ID_COMMENT, GST_TAG_COMMENT}, {    /* Any comment related to the content. */
    GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {   /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
      /* PLAY_COUNTER The number of time the item has been played. */
      /* TODO: RATING A numeric value defining how much a person likes the song/movie. The number is between 0 and 5 with decimal values possible (e.g. 2.7), 5(.0) being the highest possible rating. Other rating systems with different ranges will have to be scaled. */

      /* Technical Information */
    GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
      /* ENCODER_SETTINGS A list of the settings used for encoding this item. No specific format. */
    GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
    GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {     /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
      /* WONTFIX (already handled in another way): FPS The average frames per second of the specified item. This is typically the average number of Blocks per second. In the event that lacing is used, each laced chunk is to be counted as a seperate frame. */
    GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
      /* MEASURE In music, a measure is a unit of time in Western music like "4/4". It represents a regular grouping of beats, a meter, as indicated in musical notation by the time signature.. The majority of the contemporary rock and pop music you hear on the radio these days is written in the 4/4 time signature. */
      /* TUNING It is saved as a frequency in hertz to allow near-perfect tuning of instruments to the same tone as the musical piece (e.g. "441.34" in Hertz). The default value is 440.0 Hz. */
      /* TODO: REPLAYGAIN_GAIN The gain to apply to reach 89dB SPL on playback. This is based on the Replay Gain standard. Note that ReplayGain information can be found at all TargetType levels (track, album, etc). */
      /* TODO: REPLAYGAIN_PEAK The maximum absolute peak value of the item. This is based on the Replay Gain standard. */

      /* Identifiers */
    GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
      /* MCDI This is a binary dump of the TOC of the CDROM that this item was taken from. This holds the same information as the MCDI in ID3. */
      /* ISBN International Standard Book Number */
      /* BARCODE EAN-13 (European Article Numbering) or UPC-A (Universal Product Code) bar code identifier */
      /* CATALOG_NUMBER A label-specific string used to identify the release (TIC 01 for example). */
      /* LABEL_CODE A 4-digit or 5-digit number to identify the record label, typically printed as (LC) xxxx or (LC) 0xxxx on CDs medias or covers (only the number is stored). */
      /* LCCN Library of Congress Control Number */

      /* Commercial */
      /* PURCHASE_ITEM URL to purchase this file. This is akin to the WPAY tag in ID3. */
      /* PURCHASE_INFO Information on where to purchase this album. This is akin to the WCOM tag in ID3. */
      /* PURCHASE_OWNER Information on the person who purchased the file. This is akin to the TOWN tag in ID3. */
      /* PURCHASE_PRICE The amount paid for entity. There should only be a numeric value in here. Only numbers, no letters or symbols other than ".". For instance, you would store "15.59" instead of "$15.59USD". */
      /* PURCHASE_CURRENCY The currency type used to pay for the entity. Use ISO-4217 for the 3 letter currency code. */

      /* Legal */
    GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
    GST_MATROSKA_TAG_ID_PRODUCTION_COPYRIGHT, GST_TAG_COPYRIGHT}, {     /* The copyright information as per the production copyright holder. This is akin to the TPRO tag in ID3. */
    GST_MATROSKA_TAG_ID_LICENSE, GST_TAG_LICENSE}, {    /* The license applied to the content (like Creative Commons variants). */
    GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}
  };
  static const struct
  {
    const gchar *matroska_tagname;
    const gchar *gstreamer_tagname;
  }
  child_tag_conv[] = {
    {
    "TITLE/SORT_WITH=", GST_TAG_TITLE_SORTNAME}, {
    "ARTIST/SORT_WITH=", GST_TAG_ARTIST_SORTNAME}, {
      /* ALBUM-stuff is handled elsewhere */
    "COMPOSER/SORT_WITH=", GST_TAG_TITLE_SORTNAME}, {
    "ORIGINAL/URL=", GST_TAG_LOCATION}, {
      /* EMAIL, PHONE, FAX all can be mapped to GST_TAG_CONTACT, there is special
       * code for that later.
       */
    "TITLE/URL=", GST_TAG_HOMEPAGE}, {
    "ARTIST/URL=", GST_TAG_HOMEPAGE}, {
    "COPYRIGHT/URL=", GST_TAG_COPYRIGHT_URI}, {
    "LICENSE/URL=", GST_TAG_LICENSE_URI}, {
    "LICENSE/URL=", GST_TAG_LICENSE_URI}
  };
  GstFlowReturn ret;
  guint32 id;
  gchar *value = NULL;
  gchar *tag = NULL;
  gchar *name_with_parent = NULL;
  GstTagList *child_taglist = NULL;

  DEBUG_ELEMENT_START (common, ebml, "SimpleTag");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
    return ret;
  }

  if (parent)
    child_taglist = *p_taglist;
  else
    child_taglist = gst_tag_list_new_empty ();

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    /* read all sub-entries */

    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_TAGNAME:
        g_free (tag);
        tag = NULL;
        ret = gst_ebml_read_ascii (ebml, &id, &tag);
        GST_DEBUG_OBJECT (common->sinkpad, "TagName: %s", GST_STR_NULL (tag));
        g_free (name_with_parent);
        if (parent != NULL)
          name_with_parent = g_strdup_printf ("%s/%s", parent, tag);
        else
          name_with_parent = g_strdup (tag);
        break;

      case GST_MATROSKA_ID_TAGSTRING:
        g_free (value);
        value = NULL;
        ret = gst_ebml_read_utf8 (ebml, &id, &value);
        GST_DEBUG_OBJECT (common->sinkpad, "TagString: %s",
            GST_STR_NULL (value));
        break;

      case GST_MATROSKA_ID_SIMPLETAG:
        /* Recursive SimpleTag */
        /* This implementation requires tag name of _this_ tag to be known
         * in order to read its children. It's not in the spec, just the way
         * the code is written.
         */
        if (name_with_parent != NULL) {
          ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
              ebml, &child_taglist, name_with_parent);
          break;
        }
        /* fall-through */

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml, "SimpleTag",
            id);
        break;

      case GST_MATROSKA_ID_TAGLANGUAGE:
      case GST_MATROSKA_ID_TAGDEFAULT:
      case GST_MATROSKA_ID_TAGBINARY:
        ret = gst_ebml_read_skip (ebml);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);

  if (parent && tag && value && *value != '\0') {
    /* Don't bother mapping children tags - parent will do that */
    gchar *key_val;
    /* TODO: read LANGUAGE sub-tag, and use "key[lc]=val" form */
    key_val = g_strdup_printf ("%s=%s", name_with_parent, value);
    gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
        GST_TAG_EXTENDED_COMMENT, key_val, NULL);
    g_free (key_val);
  } else if (tag && value && *value != '\0') {
    gboolean matched = FALSE;
    guint i;

    for (i = 0; !matched && i < G_N_ELEMENTS (tag_conv); i++) {
      const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;

      const gchar *tagname_mkv = tag_conv[i].matroska_tagname;

      if (strcmp (tagname_mkv, tag) == 0) {
        GValue dest = { 0, };
        GType dest_type = gst_tag_get_type (tagname_gst);

        /* Ensure that any date string is complete */
        if (dest_type == G_TYPE_DATE) {
          guint year = 1901, month = 1, day = 1;

          /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
           * the first type */
          if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
            g_free (value);
            value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
          }
        }

        g_value_init (&dest, dest_type);
        if (gst_value_deserialize (&dest, value)) {
          gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
              tagname_gst, &dest, NULL);
        } else {
          GST_WARNING_OBJECT (common->sinkpad, "Can't transform tag '%s' with "
              "value '%s' to target type '%s'", tag, value,
              g_type_name (dest_type));
        }
        g_value_unset (&dest);
        matched = TRUE;
      }
    }
    if (!matched) {
      gchar *key_val;
      /* TODO: read LANGUAGE sub-tag, and use "key[lc]=val" form */
      key_val = g_strdup_printf ("%s=%s", tag, value);
      gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
          GST_TAG_EXTENDED_COMMENT, key_val, NULL);
      g_free (key_val);
    }
  }

  if (!parent) {
    /* Map children tags. This only supports top-anchored mapping. That is,
     * we start at toplevel tag (this tag), and see how its combinations
     * with its children can be mapped. Which means that grandchildren
     * are also combined here, with _this_ tag taken into consideration.
     * If grandchildren can be combined only with children, that combination
     * will not happen.
     */
    gint child_tags_n = gst_tag_list_n_tags (child_taglist);
    if (child_tags_n > 0) {
      gint i;
      for (i = 0; i < child_tags_n; i++) {
        gint j;
        const gchar *child_name = gst_tag_list_nth_tag_name (child_taglist, i);
        guint taglen = gst_tag_list_get_tag_size (child_taglist, child_name);
        for (j = 0; j < taglen; j++) {
          gchar *val;
          gboolean matched = FALSE;
          gchar *val_pre, *val_post;
          gint k;

          if (!gst_tag_list_get_string_index (child_taglist, child_name,
                  j, &val))
            continue;
          if (!strchr (val, '=')) {
            g_free (val);
            continue;
          }
          val_post = g_strdup (strchr (val, '=') + 1);
          val_pre = g_strdup (val);
          *(strchr (val_pre, '=') + 1) = '\0';

          for (k = 0; !matched && k < G_N_ELEMENTS (child_tag_conv); k++) {
            const gchar *tagname_gst = child_tag_conv[k].gstreamer_tagname;

            const gchar *tagname_mkv = child_tag_conv[k].matroska_tagname;

            /* TODO: Once "key[lc]=value" form support is implemented,
             * strip [lc] here. It can't be used in combined tags.
             * If a tag is not combined, leave [lc] as it is.
             */
            if (strcmp (tagname_mkv, val_pre) == 0) {
              GValue dest = { 0, };
              GType dest_type = gst_tag_get_type (tagname_gst);

              g_value_init (&dest, dest_type);
              if (gst_value_deserialize (&dest, val_post)) {
                gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
                    tagname_gst, &dest, NULL);
              } else {
                GST_WARNING_OBJECT (common->sinkpad,
                    "Can't transform complex tag '%s' " "to target type '%s'",
                    val, g_type_name (dest_type));
              }
              g_value_unset (&dest);
              matched = TRUE;
            }
          }
          if (!matched) {
            gchar *last_slash = strrchr (val_pre, '/');
            if (last_slash) {
              last_slash++;
              if (strcmp (last_slash, "EMAIL=") == 0 ||
                  strcmp (last_slash, "PHONE=") == 0 ||
                  strcmp (last_slash, "ADDRESS=") == 0 ||
                  strcmp (last_slash, "FAX=") == 0) {
                gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
                    GST_TAG_CONTACT, val_post, NULL);
                matched = TRUE;
              }
            }
          }
          if (!matched)
            gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
                GST_TAG_EXTENDED_COMMENT, val, NULL);
          g_free (val_post);
          g_free (val_pre);
          g_free (val);
        }
      }
    }
    gst_tag_list_unref (child_taglist);
  }

  g_free (tag);
  g_free (value);
  g_free (name_with_parent);

  return ret;
}


static void
gst_matroska_read_common_count_streams (GstMatroskaReadCommon * common,
    gint * a, gint * v, gint * s)
{
  gint i;
  gint video_streams = 0, audio_streams = 0, subtitle_streams = 0;

  for (i = 0; i < common->src->len; i++) {
    GstMatroskaTrackContext *stream;

    stream = g_ptr_array_index (common->src, i);
    if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
      video_streams += 1;
    else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
      audio_streams += 1;
    else if (stream->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
      subtitle_streams += 1;
  }
  *v = video_streams;
  *a = audio_streams;
  *s = subtitle_streams;
}


static void
gst_matroska_read_common_apply_target_type_foreach (const GstTagList * list,
    const gchar * tag, gpointer user_data)
{
  guint vallen;
  guint i;
  TargetTypeContext *ctx = (TargetTypeContext *) user_data;

  vallen = gst_tag_list_get_tag_size (list, tag);
  if (vallen == 0)
    return;

  for (i = 0; i < vallen; i++) {
    const GValue *val_ref;

    val_ref = gst_tag_list_get_value_index (list, tag, i);
    if (val_ref == NULL)
      continue;

    /* TODO: use the optional ctx->target_type somehow */
    if (strcmp (tag, GST_TAG_TITLE) == 0) {
      if (ctx->target_type_value >= 70 && !ctx->audio_only) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_SHOW_NAME, val_ref);
        continue;
      } else if (ctx->target_type_value >= 50) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_ALBUM, val_ref);
        continue;
      }
    } else if (strcmp (tag, GST_TAG_TITLE_SORTNAME) == 0) {
      if (ctx->target_type_value >= 70 && !ctx->audio_only) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_SHOW_SORTNAME, val_ref);
        continue;
      } else if (ctx->target_type_value >= 50) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_ALBUM_SORTNAME, val_ref);
        continue;
      }
    } else if (strcmp (tag, GST_TAG_ARTIST) == 0) {
      if (ctx->target_type_value >= 50) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_ALBUM_ARTIST, val_ref);
        continue;
      }
    } else if (strcmp (tag, GST_TAG_ARTIST_SORTNAME) == 0) {
      if (ctx->target_type_value >= 50) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_ALBUM_ARTIST_SORTNAME, val_ref);
        continue;
      }
    } else if (strcmp (tag, GST_TAG_TRACK_COUNT) == 0) {
      if (ctx->target_type_value >= 60) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_ALBUM_VOLUME_COUNT, val_ref);
        continue;
      }
    } else if (strcmp (tag, GST_TAG_TRACK_NUMBER) == 0) {
      if (ctx->target_type_value >= 60 && !ctx->audio_only) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_SHOW_SEASON_NUMBER, val_ref);
        continue;
      } else if (ctx->target_type_value >= 50 && !ctx->audio_only) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_SHOW_EPISODE_NUMBER, val_ref);
        continue;
      } else if (ctx->target_type_value >= 50) {
        gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
            GST_TAG_ALBUM_VOLUME_NUMBER, val_ref);
        continue;
      }
    }
    gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND, tag, val_ref);
  }
}


static GstTagList *
gst_matroska_read_common_apply_target_type (GstMatroskaReadCommon * common,
    GstTagList * taglist, guint64 target_type_value, gchar * target_type)
{
  TargetTypeContext ctx;
  gint a = 0;
  gint v = 0;
  gint s = 0;

  gst_matroska_read_common_count_streams (common, &a, &v, &s);

  ctx.audio_only = (a > 0 && v == 0 && s == 0);
  ctx.result = gst_tag_list_new_empty ();
  ctx.target_type_value = target_type_value;
  ctx.target_type = target_type;

  gst_tag_list_foreach (taglist,
      gst_matroska_read_common_apply_target_type_foreach, &ctx);

  gst_tag_list_unref (taglist);
  return ctx.result;
}


static GstFlowReturn
gst_matroska_read_common_parse_metadata_id_tag (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, GstTagList ** p_taglist)
{
  guint32 id;
  GstFlowReturn ret;
  GArray *chapter_targets, *edition_targets, *track_targets;
  GstTagList *taglist;
  GList *cur;
  guint64 target_type_value = 50;
  gchar *target_type = NULL;

  DEBUG_ELEMENT_START (common, ebml, "Tag");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
    return ret;
  }

  edition_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
  chapter_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
  track_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
  taglist = gst_tag_list_new_empty ();
  target_type = NULL;

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    /* read all sub-entries */

    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_SIMPLETAG:
        ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
            ebml, &taglist, NULL);
        break;

      case GST_MATROSKA_ID_TARGETS:
        g_free (target_type);
        target_type = NULL;
        target_type_value = 50;
        ret = gst_matroska_read_common_parse_metadata_targets (common, ebml,
            edition_targets, chapter_targets, track_targets,
            &target_type_value, &target_type);
        break;

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml, "Tag", id);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);

  taglist = gst_matroska_read_common_apply_target_type (common, taglist,
      target_type_value, target_type);
  g_free (target_type);

  /* if tag is chapter/edition specific - try to find that entry */
  if (G_UNLIKELY (chapter_targets->len > 0 || edition_targets->len > 0 ||
          track_targets->len > 0)) {
    gint i;
    if (chapter_targets->len > 0 || edition_targets->len > 0) {
      if (common->toc == NULL)
        GST_WARNING_OBJECT (common->sinkpad,
            "Found chapter/edition specific tag, but TOC is not present");
      else {
        cur = gst_toc_get_entries (common->toc);
        while (cur != NULL) {
          gst_matroska_read_common_parse_toc_tag (cur->data, edition_targets,
              chapter_targets, taglist);
          cur = cur->next;
        }
        common->toc_updated = TRUE;
      }
    }
    for (i = 0; i < track_targets->len; i++) {
      gint j;
      gboolean found = FALSE;
      guint64 tgt = g_array_index (track_targets, guint64, i);

      for (j = 0; j < common->src->len; j++) {
        GstMatroskaTrackContext *stream = g_ptr_array_index (common->src, j);

        if (stream->uid == tgt) {
          gst_tag_list_insert (stream->tags, taglist, GST_TAG_MERGE_REPLACE);
          stream->tags_changed = TRUE;
          found = TRUE;
        }
      }
      if (!found) {
        /* Cache the track taglist: possibly belongs to a track that will be parsed
           later in gst_matroska_demux.c:gst_matroska_demux_add_stream (...) */
        gpointer track_uid = GUINT_TO_POINTER (tgt);
        GstTagList *cached_taglist =
            g_hash_table_lookup (common->cached_track_taglists, track_uid);
        if (cached_taglist)
          gst_tag_list_insert (cached_taglist, taglist, GST_TAG_MERGE_REPLACE);
        else {
          gst_tag_list_ref (taglist);
          g_hash_table_insert (common->cached_track_taglists, track_uid,
              taglist);
        }
        GST_DEBUG_OBJECT (common->sinkpad,
            "Found track-specific tag(s), but track %" G_GUINT64_FORMAT
            " is not known yet, caching", tgt);
      }
    }
  } else
    gst_tag_list_insert (*p_taglist, taglist, GST_TAG_MERGE_APPEND);

  gst_tag_list_unref (taglist);
  g_array_unref (chapter_targets);
  g_array_unref (edition_targets);
  g_array_unref (track_targets);

  return ret;
}

GstFlowReturn
gst_matroska_read_common_parse_metadata (GstMatroskaReadCommon * common,
    GstElement * el, GstEbmlRead * ebml)
{
  GstTagList *taglist;
  GstFlowReturn ret = GST_FLOW_OK;
  guint32 id;
  GList *l;
  guint64 curpos;

  /* Make sure we don't parse a tags element twice and
   * post it's tags twice */
  curpos = gst_ebml_read_get_pos (ebml);
  for (l = common->tags_parsed; l; l = l->next) {
    guint64 *pos = l->data;

    if (*pos == curpos) {
      GST_DEBUG_OBJECT (common->sinkpad,
          "Skipping already parsed Tags at offset %" G_GUINT64_FORMAT, curpos);
      return GST_FLOW_OK;
    }
  }

  common->tags_parsed =
      g_list_prepend (common->tags_parsed, g_slice_new (guint64));
  *((guint64 *) common->tags_parsed->data) = curpos;
  /* fall-through */

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
    return ret;
  }

  taglist = gst_tag_list_new_empty ();
  gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
  common->toc_updated = FALSE;

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_TAG:
        ret = gst_matroska_read_common_parse_metadata_id_tag (common, ebml,
            &taglist);
        break;

      default:
        ret = gst_matroska_read_common_parse_skip (common, ebml, "Tags", id);
        break;
        /* FIXME: Use to limit the tags to specific pads */
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);

  if (G_LIKELY (!gst_tag_list_is_empty (taglist)))
    gst_matroska_read_common_found_global_tag (common, el, taglist);
  else
    gst_tag_list_unref (taglist);

  return ret;
}

static GstFlowReturn
gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint
    peek, const guint8 ** data)
{
  /* Caller needs to gst_adapter_unmap. */
  *data = gst_adapter_map (common->adapter, peek);
  if (*data == NULL)
    return GST_FLOW_EOS;

  return GST_FLOW_OK;
}

/*
 * Calls pull_range for (offset,size) without advancing our offset
 */
GstFlowReturn
gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64
    offset, guint size, GstBuffer ** p_buf, guint8 ** bytes)
{
  GstFlowReturn ret;

  /* Caching here actually makes much less difference than one would expect.
   * We do it mainly to avoid pulling buffers of 1 byte all the time */
  if (common->cached_buffer) {
    guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer);
    gsize cache_size = gst_buffer_get_size (common->cached_buffer);

    if (cache_offset <= common->offset &&
        (common->offset + size) <= (cache_offset + cache_size)) {
      if (p_buf)
        *p_buf = gst_buffer_copy_region (common->cached_buffer,
            GST_BUFFER_COPY_ALL, common->offset - cache_offset, size);
      if (bytes) {
        if (!common->cached_data) {
          gst_buffer_map (common->cached_buffer, &common->cached_map,
              GST_MAP_READ);
          common->cached_data = common->cached_map.data;
        }
        *bytes = common->cached_data + common->offset - cache_offset;
      }
      return GST_FLOW_OK;
    }
    /* not enough data in the cache, free cache and get a new one */
    if (common->cached_data) {
      gst_buffer_unmap (common->cached_buffer, &common->cached_map);
      common->cached_data = NULL;
    }
    gst_buffer_unref (common->cached_buffer);
    common->cached_buffer = NULL;
  }

  /* refill the cache */
  ret = gst_pad_pull_range (common->sinkpad, common->offset,
      MAX (size, 64 * 1024), &common->cached_buffer);
  if (ret != GST_FLOW_OK) {
    common->cached_buffer = NULL;
    return ret;
  }

  if (gst_buffer_get_size (common->cached_buffer) >= size) {
    if (p_buf)
      *p_buf = gst_buffer_copy_region (common->cached_buffer,
          GST_BUFFER_COPY_ALL, 0, size);
    if (bytes) {
      gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
      common->cached_data = common->cached_map.data;
      *bytes = common->cached_data;
    }
    return GST_FLOW_OK;
  }

  /* Not possible to get enough data, try a last time with
   * requesting exactly the size we need */
  gst_buffer_unref (common->cached_buffer);
  common->cached_buffer = NULL;

  ret =
      gst_pad_pull_range (common->sinkpad, common->offset, size,
      &common->cached_buffer);
  if (ret != GST_FLOW_OK) {
    GST_DEBUG_OBJECT (common->sinkpad, "pull_range returned %d", ret);
    if (p_buf)
      *p_buf = NULL;
    if (bytes)
      *bytes = NULL;
    return ret;
  }

  if (gst_buffer_get_size (common->cached_buffer) < size) {
    GST_WARNING_OBJECT (common->sinkpad, "Dropping short buffer at offset %"
        G_GUINT64_FORMAT ": wanted %u bytes, got %" G_GSIZE_FORMAT " bytes",
        common->offset, size, gst_buffer_get_size (common->cached_buffer));

    gst_buffer_unref (common->cached_buffer);
    common->cached_buffer = NULL;
    if (p_buf)
      *p_buf = NULL;
    if (bytes)
      *bytes = NULL;
    return GST_FLOW_EOS;
  }

  if (p_buf)
    *p_buf = gst_buffer_copy_region (common->cached_buffer,
        GST_BUFFER_COPY_ALL, 0, size);
  if (bytes) {
    gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
    common->cached_data = common->cached_map.data;
    *bytes = common->cached_data;
  }

  return GST_FLOW_OK;
}

static GstFlowReturn
gst_matroska_read_common_peek_pull (GstMatroskaReadCommon * common, guint peek,
    guint8 ** data)
{
  return gst_matroska_read_common_peek_bytes (common, common->offset, peek,
      NULL, data);
}

GstFlowReturn
gst_matroska_read_common_peek_id_length_pull (GstMatroskaReadCommon * common,
    GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
{
  return gst_ebml_peek_id_length (_id, _length, _needed,
      (GstPeekData) gst_matroska_read_common_peek_pull, (gpointer) common, el,
      common->offset);
}

GstFlowReturn
gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common,
    GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
{
  GstFlowReturn ret;

  ret = gst_ebml_peek_id_length (_id, _length, _needed,
      (GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common,
      el, common->offset);

  gst_adapter_unmap (common->adapter);

  return ret;
}

static GstFlowReturn
gst_matroska_read_common_read_track_encoding (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, GstMatroskaTrackContext * context)
{
  GstMatroskaTrackEncoding enc = { 0, };
  GstFlowReturn ret;
  guint32 id;

  DEBUG_ELEMENT_START (common, ebml, "ContentEncoding");
  /* Set default values */
  enc.scope = 1;
  /* All other default values are 0 */

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
    return ret;
  }

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
        guint64 num;

        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
          break;

        if (!gst_matroska_read_common_encoding_order_unique (context->encodings,
                num)) {
          GST_ERROR_OBJECT (common->sinkpad,
              "ContentEncodingOrder %" G_GUINT64_FORMAT
              "is not unique for track %" G_GUINT64_FORMAT, num, context->num);
          ret = GST_FLOW_ERROR;
          break;
        }

        GST_DEBUG_OBJECT (common->sinkpad,
            "ContentEncodingOrder: %" G_GUINT64_FORMAT, num);
        enc.order = num;
        break;
      }
      case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
        guint64 num;

        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
          break;

        if (num > 7 || num == 0) {
          GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentEncodingScope %"
              G_GUINT64_FORMAT, num);
          ret = GST_FLOW_ERROR;
          break;
        }

        GST_DEBUG_OBJECT (common->sinkpad,
            "ContentEncodingScope: %" G_GUINT64_FORMAT, num);
        enc.scope = num;

        break;
      }
      case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
        guint64 num;

        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
          break;

        if (num > 1) {
          GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentEncodingType %"
              G_GUINT64_FORMAT, num);
          ret = GST_FLOW_ERROR;
          break;
        } else if (num != 0) {
          GST_ERROR_OBJECT (common->sinkpad,
              "Encrypted tracks are not supported yet");
          ret = GST_FLOW_ERROR;
          break;
        }
        GST_DEBUG_OBJECT (common->sinkpad,
            "ContentEncodingType: %" G_GUINT64_FORMAT, num);
        enc.type = num;
        break;
      }
      case GST_MATROSKA_ID_CONTENTCOMPRESSION:{

        DEBUG_ELEMENT_START (common, ebml, "ContentCompression");

        if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
          break;

        while (ret == GST_FLOW_OK &&
            gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
          if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
            break;

          switch (id) {
            case GST_MATROSKA_ID_CONTENTCOMPALGO:{
              guint64 num;

              if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
                break;
              }
              if (num > 3) {
                GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentCompAlgo %"
                    G_GUINT64_FORMAT, num);
                ret = GST_FLOW_ERROR;
                break;
              }
              GST_DEBUG_OBJECT (common->sinkpad,
                  "ContentCompAlgo: %" G_GUINT64_FORMAT, num);
              enc.comp_algo = num;

              break;
            }
            case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
              guint8 *data;
              guint64 size;

              if ((ret =
                      gst_ebml_read_binary (ebml, &id, &data,
                          &size)) != GST_FLOW_OK) {
                break;
              }
              enc.comp_settings = data;
              enc.comp_settings_length = size;
              GST_DEBUG_OBJECT (common->sinkpad,
                  "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
              break;
            }
            default:
              GST_WARNING_OBJECT (common->sinkpad,
                  "Unknown ContentCompression subelement 0x%x - ignoring", id);
              ret = gst_ebml_read_skip (ebml);
              break;
          }
        }
        DEBUG_ELEMENT_STOP (common, ebml, "ContentCompression", ret);
        break;
      }

      case GST_MATROSKA_ID_CONTENTENCRYPTION:
        GST_ERROR_OBJECT (common->sinkpad,
            "Encrypted tracks not yet supported");
        gst_ebml_read_skip (ebml);
        ret = GST_FLOW_ERROR;
        break;
      default:
        GST_WARNING_OBJECT (common->sinkpad,
            "Unknown ContentEncoding subelement 0x%x - ignoring", id);
        ret = gst_ebml_read_skip (ebml);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
  if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
    return ret;

  /* TODO: Check if the combination of values is valid */

  g_array_append_val (context->encodings, enc);

  return ret;
}

GstFlowReturn
gst_matroska_read_common_read_track_encodings (GstMatroskaReadCommon * common,
    GstEbmlRead * ebml, GstMatroskaTrackContext * context)
{
  GstFlowReturn ret;
  guint32 id;

  DEBUG_ELEMENT_START (common, ebml, "ContentEncodings");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
    return ret;
  }

  context->encodings =
      g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
      break;

    switch (id) {
      case GST_MATROSKA_ID_CONTENTENCODING:
        ret = gst_matroska_read_common_read_track_encoding (common, ebml,
            context);
        break;
      default:
        GST_WARNING_OBJECT (common->sinkpad,
            "Unknown ContentEncodings subelement 0x%x - ignoring", id);
        ret = gst_ebml_read_skip (ebml);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
  if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
    return ret;

  /* Sort encodings according to their order */
  g_array_sort (context->encodings,
      (GCompareFunc) gst_matroska_read_common_encoding_cmp);

  return gst_matroska_decode_content_encodings (context->encodings);
}

void
gst_matroska_read_common_free_parsed_el (gpointer mem, gpointer user_data)
{
  g_slice_free (guint64, mem);
}

void
gst_matroska_read_common_init (GstMatroskaReadCommon * ctx)
{
  ctx->src = NULL;
  ctx->writing_app = NULL;
  ctx->muxing_app = NULL;
  ctx->index = NULL;
  ctx->global_tags = NULL;
  ctx->adapter = gst_adapter_new ();
  ctx->cached_track_taglists =
      g_hash_table_new_full (NULL, NULL, NULL,
      (GDestroyNotify) gst_tag_list_unref);
}

void
gst_matroska_read_common_finalize (GstMatroskaReadCommon * ctx)
{
  if (ctx->src) {
    g_ptr_array_free (ctx->src, TRUE);
    ctx->src = NULL;
  }

  if (ctx->global_tags) {
    gst_tag_list_unref (ctx->global_tags);
    ctx->global_tags = NULL;
  }

  g_object_unref (ctx->adapter);
  g_hash_table_remove_all (ctx->cached_track_taglists);
  g_hash_table_unref (ctx->cached_track_taglists);

}

void
gst_matroska_read_common_reset (GstElement * element,
    GstMatroskaReadCommon * ctx)
{
  guint i;

  GST_LOG_OBJECT (ctx->sinkpad, "resetting read context");

  /* reset input */
  ctx->state = GST_MATROSKA_READ_STATE_START;

  /* clean up existing streams if any */
  if (ctx->src) {
    g_assert (ctx->src->len == ctx->num_streams);
    for (i = 0; i < ctx->src->len; i++) {
      GstMatroskaTrackContext *context = g_ptr_array_index (ctx->src, i);

      if (context->pad != NULL)
        gst_element_remove_pad (element, context->pad);

      gst_caps_replace (&context->caps, NULL);
      gst_matroska_track_free (context);
    }
    g_ptr_array_free (ctx->src, TRUE);
  }
  ctx->src = g_ptr_array_new ();
  ctx->num_streams = 0;

  /* reset media info */
  g_free (ctx->writing_app);
  ctx->writing_app = NULL;
  g_free (ctx->muxing_app);
  ctx->muxing_app = NULL;

  /* reset stream type */
  ctx->is_webm = FALSE;
  ctx->has_video = FALSE;

  /* reset indexes */
  if (ctx->index) {
    g_array_free (ctx->index, TRUE);
    ctx->index = NULL;
  }

  /* reset timers */
  ctx->time_scale = 1000000;
  ctx->created = G_MININT64;

  /* cues/tracks/segmentinfo */
  ctx->index_parsed = FALSE;
  ctx->segmentinfo_parsed = FALSE;
  ctx->attachments_parsed = FALSE;
  ctx->chapters_parsed = FALSE;

  /* tags */
  ctx->global_tags_changed = FALSE;
  g_list_foreach (ctx->tags_parsed,
      (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
  g_list_free (ctx->tags_parsed);
  ctx->tags_parsed = NULL;
  if (ctx->global_tags) {
    gst_tag_list_unref (ctx->global_tags);
  }
  ctx->global_tags = gst_tag_list_new_empty ();
  gst_tag_list_set_scope (ctx->global_tags, GST_TAG_SCOPE_GLOBAL);

  gst_segment_init (&ctx->segment, GST_FORMAT_TIME);
  ctx->offset = 0;

  if (ctx->cached_buffer) {
    if (ctx->cached_data) {
      gst_buffer_unmap (ctx->cached_buffer, &ctx->cached_map);
      ctx->cached_data = NULL;
    }
    gst_buffer_unref (ctx->cached_buffer);
    ctx->cached_buffer = NULL;
  }

  /* free chapters TOC if any */
  if (ctx->toc) {
    gst_toc_unref (ctx->toc);
    ctx->toc = NULL;
  }
}

/* call with object lock held */
void
gst_matroska_read_common_reset_streams (GstMatroskaReadCommon * common,
    GstClockTime time, gboolean full)
{
  gint i;

  GST_DEBUG_OBJECT (common->sinkpad, "resetting stream state");

  g_assert (common->src->len == common->num_streams);
  for (i = 0; i < common->src->len; i++) {
    GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
    context->pos = time;
    context->set_discont = TRUE;
    context->eos = FALSE;
    context->from_time = GST_CLOCK_TIME_NONE;
    if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
      GstMatroskaTrackVideoContext *videocontext =
          (GstMatroskaTrackVideoContext *) context;
      /* demux object lock held by caller */
      videocontext->earliest_time = GST_CLOCK_TIME_NONE;
    }
  }
}

gboolean
gst_matroska_read_common_tracknumber_unique (GstMatroskaReadCommon * common,
    guint64 num)
{
  gint i;

  g_assert (common->src->len == common->num_streams);
  for (i = 0; i < common->src->len; i++) {
    GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);

    if (context->num == num)
      return FALSE;
  }

  return TRUE;
}
