/* 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-parse.c: matroska file/stream 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.
 */

/* TODO: check CRC32 if present
 * TODO: there can be a segment after the first segment. Handle like
 *       chained oggs. Fixes #334082
 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
 *                     http://samples.mplayerhq.hu/Matroska/
 * TODO: check if parseing is done correct for all codecs according to spec
 * TODO: seeking with incomplete or without CUE
 */

/**
 * SECTION:element-matroskaparse
 *
 * matroskaparse parsees a Matroska file into the different contained streams.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskaparse ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
 * ]| This pipeline parsees a Matroska file and outputs the contained Vorbis audio.
 * </refsect2>
 */


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

#include <math.h>
#include <string.h>
#include <glib/gprintf.h>

/* For AVI compatibility mode
   and for fourcc stuff */
#include <gst/riff/riff-read.h>
#include <gst/riff/riff-ids.h>
#include <gst/riff/riff-media.h>

#include <gst/tag/tag.h>

#include <gst/pbutils/pbutils.h>

#include "matroska-parse.h"
#include "matroska-ids.h"

GST_DEBUG_CATEGORY_STATIC (matroskaparse_debug);
#define GST_CAT_DEFAULT matroskaparse_debug

#define DEBUG_ELEMENT_START(parse, ebml, element) \
    GST_DEBUG_OBJECT (parse, "Parsing " element " element at offset %" \
        G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))

#define DEBUG_ELEMENT_STOP(parse, ebml, element, ret) \
    GST_DEBUG_OBJECT (parse, "Parsing " element " element " \
        " finished with '%s'", gst_flow_get_name (ret))

enum
{
  ARG_0,
  ARG_METADATA,
  ARG_STREAMINFO
};

static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
        "video/x-matroska-3d; audio/webm; video/webm")
    );

static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
        "video/x-matroska-3d; audio/webm; video/webm")
    );

static GstFlowReturn gst_matroska_parse_parse_id (GstMatroskaParse * parse,
    guint32 id, guint64 length, guint needed);

/* element functions */
//static void gst_matroska_parse_loop (GstPad * pad);

static gboolean gst_matroska_parse_element_send_event (GstElement * element,
    GstEvent * event);
static gboolean gst_matroska_parse_element_query (GstElement * element,
    GstQuery * query);

/* pad functions */
static gboolean gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
    GstPad * pad, GstEvent * event);
static gboolean gst_matroska_parse_handle_src_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
    GstObject * parent, GstQuery * query);

static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
    GstObject * parent, GstBuffer * buffer);

static GstStateChangeReturn
gst_matroska_parse_change_state (GstElement * element,
    GstStateChange transition);
#if 0
static void
gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
static GstIndex *gst_matroska_parse_get_index (GstElement * element);
#endif

/* stream methods */
static void gst_matroska_parse_reset (GstElement * element);
static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
    guint64 offset);

GType gst_matroska_parse_get_type (void);
#define parent_class gst_matroska_parse_parent_class
G_DEFINE_TYPE (GstMatroskaParse, gst_matroska_parse, GST_TYPE_ELEMENT);

static void
gst_matroska_parse_finalize (GObject * object)
{
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);

  if (parse->common.src) {
    g_ptr_array_free (parse->common.src, TRUE);
    parse->common.src = NULL;
  }

  if (parse->common.global_tags) {
    gst_tag_list_unref (parse->common.global_tags);
    parse->common.global_tags = NULL;
  }

  g_object_unref (parse->common.adapter);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;

  GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
      "Matroska parser");

  gobject_class->finalize = gst_matroska_parse_finalize;

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
  gstelement_class->send_event =
      GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
  gstelement_class->query =
      GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);

#if 0
  gstelement_class->set_index =
      GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
  gstelement_class->get_index =
      GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
#endif

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_templ));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sink_templ));

  gst_element_class_set_static_metadata (gstelement_class,
      "Matroska parser", "Codec/Parser",
      "Parses Matroska/WebM streams into video/audio/subtitles",
      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
}

static void
gst_matroska_parse_init (GstMatroskaParse * parse)
{
  parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
      "sink");
  gst_pad_set_chain_function (parse->common.sinkpad,
      GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
  gst_pad_set_event_function (parse->common.sinkpad,
      GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
  gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);

  parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
  gst_pad_set_event_function (parse->srcpad,
      GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
  gst_pad_set_query_function (parse->srcpad,
      GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
  gst_pad_use_fixed_caps (parse->srcpad);

  gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);

  /* initial stream no. */
  parse->common.src = NULL;

  parse->common.writing_app = NULL;
  parse->common.muxing_app = NULL;
  parse->common.index = NULL;
  parse->common.global_tags = NULL;

  parse->common.adapter = gst_adapter_new ();

  GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);

  /* finish off */
  gst_matroska_parse_reset (GST_ELEMENT (parse));
}

static void
gst_matroska_track_free (GstMatroskaTrackContext * track)
{
  g_free (track->codec_id);
  g_free (track->codec_name);
  g_free (track->name);
  g_free (track->language);
  g_free (track->codec_priv);
  g_free (track->codec_state);

  if (track->encodings != NULL) {
    int i;

    for (i = 0; i < track->encodings->len; ++i) {
      GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
          GstMatroskaTrackEncoding,
          i);

      g_free (enc->comp_settings);
    }
    g_array_free (track->encodings, TRUE);
  }

  if (track->pending_tags)
    gst_tag_list_unref (track->pending_tags);

  if (track->index_table)
    g_array_free (track->index_table, TRUE);

  g_free (track);
}

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

static void
gst_matroska_parse_reset (GstElement * element)
{
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
  guint i;

  GST_DEBUG_OBJECT (parse, "Resetting state");

  /* reset input */
  parse->common.state = GST_MATROSKA_READ_STATE_START;

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

      gst_caps_replace (&context->caps, NULL);
      gst_matroska_track_free (context);
    }
    g_ptr_array_free (parse->common.src, TRUE);
  }
  parse->common.src = g_ptr_array_new ();

  parse->common.num_streams = 0;
  parse->num_a_streams = 0;
  parse->num_t_streams = 0;
  parse->num_v_streams = 0;

  /* reset media info */
  g_free (parse->common.writing_app);
  parse->common.writing_app = NULL;
  g_free (parse->common.muxing_app);
  parse->common.muxing_app = NULL;

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

  /* reset timers */
  parse->clock = NULL;
  parse->common.time_scale = 1000000;
  parse->common.created = G_MININT64;

  parse->common.index_parsed = FALSE;
  parse->tracks_parsed = FALSE;
  parse->common.segmentinfo_parsed = FALSE;
  parse->common.attachments_parsed = FALSE;

  g_list_foreach (parse->common.tags_parsed,
      (GFunc) gst_matroska_parse_free_parsed_el, NULL);
  g_list_free (parse->common.tags_parsed);
  parse->common.tags_parsed = NULL;

  g_list_foreach (parse->seek_parsed,
      (GFunc) gst_matroska_parse_free_parsed_el, NULL);
  g_list_free (parse->seek_parsed);
  parse->seek_parsed = NULL;

  gst_segment_init (&parse->common.segment, GST_FORMAT_TIME);
  parse->last_stop_end = GST_CLOCK_TIME_NONE;
  parse->seek_block = 0;

  parse->common.offset = 0;
  parse->cluster_time = GST_CLOCK_TIME_NONE;
  parse->cluster_offset = 0;
  parse->next_cluster_offset = 0;
  parse->index_offset = 0;
  parse->seekable = FALSE;
  parse->need_newsegment = TRUE;
  parse->building_index = FALSE;
  if (parse->seek_event) {
    gst_event_unref (parse->seek_event);
    parse->seek_event = NULL;
  }

  parse->seek_index = NULL;
  parse->seek_entry = 0;

  if (parse->close_segment) {
    gst_event_unref (parse->close_segment);
    parse->close_segment = NULL;
  }

  if (parse->new_segment) {
    gst_event_unref (parse->new_segment);
    parse->new_segment = NULL;
  }
#if 0
  if (parse->common.element_index) {
    gst_object_unref (parse->common.element_index);
    parse->common.element_index = NULL;
  }
  parse->common.element_index_writer_id = -1;
#endif

  if (parse->common.global_tags) {
    gst_tag_list_unref (parse->common.global_tags);
  }
  parse->common.global_tags = gst_tag_list_new_empty ();

  if (parse->common.cached_buffer) {
    gst_buffer_unref (parse->common.cached_buffer);
    parse->common.cached_buffer = NULL;
  }

  if (parse->streamheader != NULL) {
    gst_buffer_unref (parse->streamheader);
    parse->streamheader = NULL;
  }
}

static GstFlowReturn
gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
{
  GstMatroskaTrackContext *context;
  GstFlowReturn ret;
  guint32 id;

  DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");

  /* start with the master */
  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
    return ret;
  }

  /* allocate generic... if we know the type, we'll g_renew()
   * with the precise type */
  context = g_new0 (GstMatroskaTrackContext, 1);
  g_ptr_array_add (parse->common.src, context);
  context->index = parse->common.num_streams;
  context->index_writer_id = -1;
  context->type = 0;            /* no type yet */
  context->default_duration = 0;
  context->pos = 0;
  context->set_discont = TRUE;
  context->timecodescale = 1.0;
  context->flags =
      GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
      GST_MATROSKA_TRACK_LACING;
  context->last_flow = GST_FLOW_OK;
  context->to_offset = G_MAXINT64;
  context->alignment = 1;
  parse->common.num_streams++;
  g_assert (parse->common.src->len == parse->common.num_streams);

  GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);

  /* try reading the trackentry headers */
  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 (unique stream ID) */
      case GST_MATROSKA_ID_TRACKNUMBER:{
        guint64 num;

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

        if (num == 0) {
          GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
          ret = GST_FLOW_ERROR;
          break;
        } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
                num)) {
          GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
              " is not unique", num);
          ret = GST_FLOW_ERROR;
          break;
        }

        GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
        context->num = num;
        break;
      }
        /* track UID (unique identifier) */
      case GST_MATROSKA_ID_TRACKUID:{
        guint64 num;

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

        if (num == 0) {
          GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
          ret = GST_FLOW_ERROR;
          break;
        }

        GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
        context->uid = num;
        break;
      }

        /* track type (video, audio, combined, subtitle, etc.) */
      case GST_MATROSKA_ID_TRACKTYPE:{
        guint64 track_type;

        if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
          break;
        }

        if (context->type != 0 && context->type != track_type) {
          GST_WARNING_OBJECT (parse,
              "More than one tracktype defined in a TrackEntry - skipping");
          break;
        } else if (track_type < 1 || track_type > 254) {
          GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
              track_type);
          break;
        }

        GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);

        /* ok, so we're actually going to reallocate this thing */
        switch (track_type) {
          case GST_MATROSKA_TRACK_TYPE_VIDEO:
            gst_matroska_track_init_video_context (&context);
            break;
          case GST_MATROSKA_TRACK_TYPE_AUDIO:
            gst_matroska_track_init_audio_context (&context);
            break;
          case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
            gst_matroska_track_init_subtitle_context (&context);
            break;
          case GST_MATROSKA_TRACK_TYPE_COMPLEX:
          case GST_MATROSKA_TRACK_TYPE_LOGO:
          case GST_MATROSKA_TRACK_TYPE_BUTTONS:
          case GST_MATROSKA_TRACK_TYPE_CONTROL:
          default:
            GST_WARNING_OBJECT (parse,
                "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
                track_type);
            context->type = 0;
            break;
        }
        g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
            = context;
        break;
      }

        /* tracktype specific stuff for video */
      case GST_MATROSKA_ID_TRACKVIDEO:{
        GstMatroskaTrackVideoContext *videocontext;

        DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");

        if (!gst_matroska_track_init_video_context (&context)) {
          GST_WARNING_OBJECT (parse,
              "TrackVideo element in non-video track - ignoring track");
          ret = GST_FLOW_ERROR;
          break;
        } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
          break;
        }
        videocontext = (GstMatroskaTrackVideoContext *) context;
        g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
            = context;

        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) {
              /* Should be one level up but some broken muxers write it here. */
            case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
              guint64 num;

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

              if (num == 0) {
                GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
                break;
              }

              GST_DEBUG_OBJECT (parse,
                  "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
              context->default_duration = num;
              break;
            }

              /* video framerate */
              /* NOTE: This one is here only for backward compatibility.
               * Use _TRACKDEFAULDURATION one level up. */
            case GST_MATROSKA_ID_VIDEOFRAMERATE:{
              gdouble num;

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

              if (num <= 0.0) {
                GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
                break;
              }

              GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
              if (context->default_duration == 0)
                context->default_duration =
                    gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
              videocontext->default_fps = num;
              break;
            }

              /* width of the size to display the video at */
            case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
              guint64 num;

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

              if (num == 0) {
                GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
                break;
              }

              GST_DEBUG_OBJECT (parse,
                  "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
              videocontext->display_width = num;
              break;
            }

              /* height of the size to display the video at */
            case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
              guint64 num;

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

              if (num == 0) {
                GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
                break;
              }

              GST_DEBUG_OBJECT (parse,
                  "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
              videocontext->display_height = num;
              break;
            }

              /* width of the video in the file */
            case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
              guint64 num;

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

              if (num == 0) {
                GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
                break;
              }

              GST_DEBUG_OBJECT (parse,
                  "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
              videocontext->pixel_width = num;
              break;
            }

              /* height of the video in the file */
            case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
              guint64 num;

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

              if (num == 0) {
                GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
                break;
              }

              GST_DEBUG_OBJECT (parse,
                  "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
              videocontext->pixel_height = num;
              break;
            }

              /* whether the video is interlaced */
            case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
              guint64 num;

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

              if (num)
                context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
              else
                context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
              GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
                  (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
                  0);
              break;
            }

              /* aspect ratio behaviour */
            case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
              guint64 num;

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

              if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
                  num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
                  num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
                GST_WARNING_OBJECT (parse,
                    "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
                break;
              }
              GST_DEBUG_OBJECT (parse,
                  "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
              videocontext->asr_mode = num;
              break;
            }

              /* colourspace (only matters for raw video) fourcc */
            case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
              guint8 *data;
              guint64 datalen;

              if ((ret =
                      gst_ebml_read_binary (ebml, &id, &data,
                          &datalen)) != GST_FLOW_OK)
                break;

              if (datalen != 4) {
                g_free (data);
                GST_WARNING_OBJECT (parse,
                    "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
                    datalen);
                break;
              }

              memcpy (&videocontext->fourcc, data, 4);
              GST_DEBUG_OBJECT (parse,
                  "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
                  GST_FOURCC_ARGS (videocontext->fourcc));
              g_free (data);
              break;
            }

            default:
              GST_WARNING_OBJECT (parse,
                  "Unknown TrackVideo subelement 0x%x - ignoring", id);
              /* fall through */
            case GST_MATROSKA_ID_VIDEOSTEREOMODE:
            case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
            case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
            case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
            case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
            case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
            case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
              ret = gst_ebml_read_skip (ebml);
              break;
          }
        }

        DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
        break;
      }

        /* tracktype specific stuff for audio */
      case GST_MATROSKA_ID_TRACKAUDIO:{
        GstMatroskaTrackAudioContext *audiocontext;

        DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");

        if (!gst_matroska_track_init_audio_context (&context)) {
          GST_WARNING_OBJECT (parse,
              "TrackAudio element in non-audio track - ignoring track");
          ret = GST_FLOW_ERROR;
          break;
        }

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

        audiocontext = (GstMatroskaTrackAudioContext *) context;
        g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
            = context;

        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) {
              /* samplerate */
            case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
              gdouble num;

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


              if (num <= 0.0) {
                GST_WARNING_OBJECT (parse,
                    "Invalid TrackAudioSamplingFrequency %lf", num);
                break;
              }

              GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
              audiocontext->samplerate = num;
              break;
            }

              /* bitdepth */
            case GST_MATROSKA_ID_AUDIOBITDEPTH:{
              guint64 num;

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

              if (num == 0) {
                GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
                break;
              }

              GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
                  num);
              audiocontext->bitdepth = num;
              break;
            }

              /* channels */
            case GST_MATROSKA_ID_AUDIOCHANNELS:{
              guint64 num;

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

              if (num == 0) {
                GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
                break;
              }

              GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
                  num);
              audiocontext->channels = num;
              break;
            }

            default:
              GST_WARNING_OBJECT (parse,
                  "Unknown TrackAudio subelement 0x%x - ignoring", id);
              /* fall through */
            case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
            case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
              ret = gst_ebml_read_skip (ebml);
              break;
          }
        }

        DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);

        break;
      }

        /* codec identifier */
      case GST_MATROSKA_ID_CODECID:{
        gchar *text;

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

        GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
        context->codec_id = text;
        break;
      }

        /* codec private data */
      case GST_MATROSKA_ID_CODECPRIVATE:{
        guint8 *data;
        guint64 size;

        if ((ret =
                gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
          break;

        context->codec_priv = data;
        context->codec_priv_size = size;

        GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
            size);
        break;
      }

        /* name of the codec */
      case GST_MATROSKA_ID_CODECNAME:{
        gchar *text;

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

        GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
        context->codec_name = text;
        break;
      }

        /* name of this track */
      case GST_MATROSKA_ID_TRACKNAME:{
        gchar *text;

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

        context->name = text;
        GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
        break;
      }

        /* language (matters for audio/subtitles, mostly) */
      case GST_MATROSKA_ID_TRACKLANGUAGE:{
        gchar *text;

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


        context->language = text;

        /* fre-ca => fre */
        if (strlen (context->language) >= 4 && context->language[3] == '-')
          context->language[3] = '\0';

        GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
            GST_STR_NULL (context->language));
        break;
      }

        /* whether this is actually used */
      case GST_MATROSKA_ID_TRACKFLAGENABLED:{
        guint64 num;

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

        if (num)
          context->flags |= GST_MATROSKA_TRACK_ENABLED;
        else
          context->flags &= ~GST_MATROSKA_TRACK_ENABLED;

        GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
            (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
        break;
      }

        /* whether it's the default for this track type */
      case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
        guint64 num;

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

        if (num)
          context->flags |= GST_MATROSKA_TRACK_DEFAULT;
        else
          context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;

        GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
            (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
        break;
      }

        /* whether the track must be used during playback */
      case GST_MATROSKA_ID_TRACKFLAGFORCED:{
        guint64 num;

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

        if (num)
          context->flags |= GST_MATROSKA_TRACK_FORCED;
        else
          context->flags &= ~GST_MATROSKA_TRACK_FORCED;

        GST_DEBUG_OBJECT (parse, "TrackForced: %d",
            (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
        break;
      }

        /* lacing (like MPEG, where blocks don't end/start on frame
         * boundaries) */
      case GST_MATROSKA_ID_TRACKFLAGLACING:{
        guint64 num;

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

        if (num)
          context->flags |= GST_MATROSKA_TRACK_LACING;
        else
          context->flags &= ~GST_MATROSKA_TRACK_LACING;

        GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
            (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
        break;
      }

        /* default length (in time) of one data block in this track */
      case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
        guint64 num;

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


        if (num == 0) {
          GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
          break;
        }

        GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
            num);
        context->default_duration = num;
        break;
      }

      case GST_MATROSKA_ID_CONTENTENCODINGS:{
        ret = gst_matroska_read_common_read_track_encodings (&parse->common,
            ebml, context);
        break;
      }

      case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
        gdouble num;

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

        if (num <= 0.0) {
          GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
          break;
        }

        GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
        context->timecodescale = num;
        break;
      }

      default:
        GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
        /* pass-through */

        /* we ignore these because they're nothing useful (i.e. crap)
         * or simply not implemented yet. */
      case GST_MATROSKA_ID_TRACKMINCACHE:
      case GST_MATROSKA_ID_TRACKMAXCACHE:
      case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
      case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
      case GST_MATROSKA_ID_TRACKOVERLAY:
      case GST_MATROSKA_ID_TRACKTRANSLATE:
      case GST_MATROSKA_ID_TRACKOFFSET:
      case GST_MATROSKA_ID_CODECSETTINGS:
      case GST_MATROSKA_ID_CODECINFOURL:
      case GST_MATROSKA_ID_CODECDOWNLOADURL:
      case GST_MATROSKA_ID_CODECDECODEALL:
        ret = gst_ebml_read_skip (ebml);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);

  /* Decode codec private data if necessary */
  if (context->encodings && context->encodings->len > 0 && context->codec_priv
      && context->codec_priv_size > 0) {
    if (!gst_matroska_decode_data (context->encodings,
            &context->codec_priv, &context->codec_priv_size,
            GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
      GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
      ret = GST_FLOW_ERROR;
    }
  }

  if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
          && ret != GST_FLOW_EOS)) {
    if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
      GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");

    parse->common.num_streams--;
    g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
    g_assert (parse->common.src->len == parse->common.num_streams);
    if (context) {
      gst_matroska_track_free (context);
    }

    return ret;
  }

  if ((context->language == NULL || *context->language == '\0') &&
      (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
          context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
    GST_LOG ("stream %d: language=eng (assuming default)", context->index);
    context->language = g_strdup ("eng");
  }


  /* tadaah! */
  return ret;
}

static gboolean
gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
    GstQuery * query)
{
  gboolean res = FALSE;
  GstMatroskaTrackContext *context = NULL;

  if (pad) {
    context = gst_pad_get_element_private (pad);
  }

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;

      gst_query_parse_position (query, &format, NULL);

      if (format == GST_FORMAT_TIME) {
        GST_OBJECT_LOCK (parse);
        if (context)
          gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
        else
          gst_query_set_position (query, GST_FORMAT_TIME,
              parse->common.segment.position);
        GST_OBJECT_UNLOCK (parse);
      } else if (format == GST_FORMAT_DEFAULT && context
          && context->default_duration) {
        GST_OBJECT_LOCK (parse);
        gst_query_set_position (query, GST_FORMAT_DEFAULT,
            context->pos / context->default_duration);
        GST_OBJECT_UNLOCK (parse);
      } else {
        GST_DEBUG_OBJECT (parse,
            "only position query in TIME and DEFAULT format is supported");
      }

      res = TRUE;
      break;
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;

      gst_query_parse_duration (query, &format, NULL);

      if (format == GST_FORMAT_TIME) {
        GST_OBJECT_LOCK (parse);
        gst_query_set_duration (query, GST_FORMAT_TIME,
            parse->common.segment.duration);
        GST_OBJECT_UNLOCK (parse);
      } else if (format == GST_FORMAT_DEFAULT && context
          && context->default_duration) {
        GST_OBJECT_LOCK (parse);
        gst_query_set_duration (query, GST_FORMAT_DEFAULT,
            parse->common.segment.duration / context->default_duration);
        GST_OBJECT_UNLOCK (parse);
      } else {
        GST_DEBUG_OBJECT (parse,
            "only duration query in TIME and DEFAULT format is supported");
      }

      res = TRUE;
      break;
    }

    case GST_QUERY_SEEKING:
    {
      GstFormat fmt;

      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
      if (fmt == GST_FORMAT_TIME) {
        gboolean seekable;

        /* assuming we'll be able to get an index ... */
        seekable = parse->seekable;

        gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
            0, parse->common.segment.duration);
        res = TRUE;
      }
      break;
    }
    default:
      res = gst_pad_query_default (pad, (GstObject *) parse, query);
      break;
  }

  return res;
}

static gboolean
gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
{
  return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
}

static gboolean
gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  gboolean ret;
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);

  ret = gst_matroska_parse_query (parse, pad, query);

  return ret;
}

/* returns FALSE if there are no pads to deliver event to,
 * otherwise TRUE (whatever the outcome of event sending),
 * takes ownership of the passed event! */
static gboolean
gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
{
  gboolean ret = FALSE;

  g_return_val_if_fail (event != NULL, FALSE);

  GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
      GST_EVENT_TYPE_NAME (event));

  gst_pad_push_event (parse->srcpad, event);

  return ret;
}

static gboolean
gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
{
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
  gboolean res;

  g_return_val_if_fail (event != NULL, FALSE);

  if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
    res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
  } else {
    GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
        GST_EVENT_TYPE_NAME (event));
    res = FALSE;
  }
  gst_event_unref (event);
  return res;
}

/* searches for a cluster start from @pos,
 * return GST_FLOW_OK and cluster position in @pos if found */
static GstFlowReturn
gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
{
  gint64 newpos = *pos;
  gint64 orig_offset;
  GstFlowReturn ret = GST_FLOW_OK;
  const guint chunk = 64 * 1024;
  GstBuffer *buf;
  GstMapInfo map;
  gpointer data;
  gsize size;
  guint64 length;
  guint32 id;
  guint needed;

  orig_offset = parse->common.offset;

  /* read in at newpos and scan for ebml cluster id */
  while (1) {
    GstByteReader reader;
    gint cluster_pos;

    buf = NULL;
    ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
    if (ret != GST_FLOW_OK)
      break;
    GST_DEBUG_OBJECT (parse,
        "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
        gst_buffer_get_size (buf), newpos);
    gst_buffer_map (buf, &map, GST_MAP_READ);
    data = map.data;
    size = map.size;
    gst_byte_reader_init (&reader, data, size);
    cluster_pos = 0;
  resume:
    cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
        GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
    if (cluster_pos >= 0) {
      newpos += cluster_pos;
      GST_DEBUG_OBJECT (parse,
          "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
      /* extra checks whether we really sync'ed to a cluster:
       * - either it is the first and only cluster
       * - either there is a cluster after this one
       * - either cluster length is undefined
       */
      /* ok if first cluster (there may not a subsequent one) */
      if (newpos == parse->first_cluster_offset) {
        GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
        break;
      }
      parse->common.offset = newpos;
      ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
          GST_ELEMENT_CAST (parse), &id, &length, &needed);
      if (ret != GST_FLOW_OK)
        goto resume;
      g_assert (id == GST_MATROSKA_ID_CLUSTER);
      GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
          length, needed);
      /* ok if undefined length or first cluster */
      if (length == G_MAXUINT64) {
        GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
        break;
      }
      /* skip cluster */
      parse->common.offset += length + needed;
      ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
          GST_ELEMENT_CAST (parse), &id, &length, &needed);
      if (ret != GST_FLOW_OK)
        goto resume;
      GST_DEBUG_OBJECT (parse, "next element is %scluster",
          id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
      if (id == GST_MATROSKA_ID_CLUSTER)
        break;
      /* not ok, resume */
      goto resume;
    } else {
      /* partial cluster id may have been in tail of buffer */
      newpos += MAX (size, 4) - 3;
      gst_buffer_unmap (buf, &map);
      gst_buffer_unref (buf);
      buf = NULL;
    }
  }

  if (buf) {
    gst_buffer_unmap (buf, &map);
    gst_buffer_unref (buf);
    buf = NULL;
  }

  parse->common.offset = orig_offset;
  *pos = newpos;
  return ret;
}


static gboolean
gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
    GstPad * pad, GstEvent * event)
{
  GstMatroskaIndex *entry = NULL;
  GstSeekFlags flags;
  GstSeekType cur_type, stop_type;
  GstFormat format;
  gdouble rate;
  gint64 cur, stop;
  GstMatroskaTrackContext *track = NULL;
  GstSegment seeksegment = { 0, };
  gboolean update;

  if (pad)
    track = gst_pad_get_element_private (pad);

  track = gst_matroska_read_common_get_seek_track (&parse->common, track);

  gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
      &stop_type, &stop);

  /* we can only seek on time */
  if (format != GST_FORMAT_TIME) {
    GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
    return FALSE;
  }

  /* copy segment, we need this because we still need the old
   * segment when we close the current segment. */
  memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));

  if (event) {
    GST_DEBUG_OBJECT (parse, "configuring seek");
    gst_segment_do_seek (&seeksegment, rate, format, flags,
        cur_type, cur, stop_type, stop, &update);
  }

  GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);

  /* check sanity before we start flushing and all that */
  GST_OBJECT_LOCK (parse);
  if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
              seeksegment.position, &parse->seek_index, &parse->seek_entry,
              FALSE)) == NULL) {
    /* pull mode without index can scan later on */
    GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
    GST_OBJECT_UNLOCK (parse);
    return FALSE;
  }
  GST_DEBUG_OBJECT (parse, "Seek position looks sane");
  GST_OBJECT_UNLOCK (parse);

  /* need to seek to cluster start to pick up cluster time */
  /* upstream takes care of flushing and all that
   * ... and newsegment event handling takes care of the rest */
  return perform_seek_to_offset (parse, entry->pos
      + parse->common.ebml_segment_start);
}

/*
 * Handle whether we can perform the seek event or if we have to let the chain
 * function handle seeks to build the seek indexes first.
 */
static gboolean
gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
    GstEvent * event)
{
  GstSeekFlags flags;
  GstSeekType cur_type, stop_type;
  GstFormat format;
  gdouble rate;
  gint64 cur, stop;

  gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
      &stop_type, &stop);

  /* sanity checks */

  /* we can only seek on time */
  if (format != GST_FORMAT_TIME) {
    GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
    return FALSE;
  }

  if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
    GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
    return FALSE;
  }

  if (!(flags & GST_SEEK_FLAG_FLUSH)) {
    GST_DEBUG_OBJECT (parse,
        "Non-flushing seek not supported in streaming mode");
    return FALSE;
  }

  if (flags & GST_SEEK_FLAG_SEGMENT) {
    GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
    return FALSE;
  }

  /* check for having parsed index already */
  if (!parse->common.index_parsed) {
    gboolean building_index;
    guint64 offset = 0;

    if (!parse->index_offset) {
      GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
      return FALSE;
    }

    GST_OBJECT_LOCK (parse);
    /* handle the seek event in the chain function */
    parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
    /* no more seek can be issued until state reset to _DATA */

    /* copy the event */
    if (parse->seek_event)
      gst_event_unref (parse->seek_event);
    parse->seek_event = gst_event_ref (event);

    /* set the building_index flag so that only one thread can setup the
     * structures for index seeking. */
    building_index = parse->building_index;
    if (!building_index) {
      parse->building_index = TRUE;
      offset = parse->index_offset;
    }
    GST_OBJECT_UNLOCK (parse);

    if (!building_index) {
      /* seek to the first subindex or legacy index */
      GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
      return perform_seek_to_offset (parse, offset);
    }

    /* well, we are handling it already */
    return TRUE;
  }

  /* delegate to tweaked regular seek */
  return gst_matroska_parse_handle_seek_event (parse, pad, event);
}

static gboolean
gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
  gboolean res = TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      /* no seeking until we are (safely) ready */
      if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
        GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
        return FALSE;
      }
      res = gst_matroska_parse_handle_seek_push (parse, pad, event);
      gst_event_unref (event);
      break;

    case GST_EVENT_QOS:
    {
      GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
      if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
        GstMatroskaTrackVideoContext *videocontext =
            (GstMatroskaTrackVideoContext *) context;
        gdouble proportion;
        GstClockTimeDiff diff;
        GstClockTime timestamp;

        gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);

        GST_OBJECT_LOCK (parse);
        videocontext->earliest_time = timestamp + diff;
        GST_OBJECT_UNLOCK (parse);
      }
      res = TRUE;
      gst_event_unref (event);
      break;
    }

      /* events we don't need to handle */
    case GST_EVENT_NAVIGATION:
      gst_event_unref (event);
      res = FALSE;
      break;

    case GST_EVENT_LATENCY:
    default:
      res = gst_pad_push_event (parse->common.sinkpad, event);
      break;
  }

  return res;
}

static GstFlowReturn
gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint32 id;

  DEBUG_ELEMENT_START (parse, ebml, "Tracks");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", 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 track within the "all-tracks" header */
      case GST_MATROSKA_ID_TRACKENTRY:
        ret = gst_matroska_parse_add_stream (parse, ebml);
        break;

      default:
        ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
            "Track", id);
        break;
    }
  }
  DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);

  parse->tracks_parsed = TRUE;

  return ret;
}

/*
 * Read signed/unsigned "EBML" numbers.
 * Return: number of bytes processed.
 */

static gint
gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
{
  gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
  guint64 total;

  if (size <= 0) {
    return -1;
  }

  total = data[0];
  while (read <= 8 && !(total & len_mask)) {
    read++;
    len_mask >>= 1;
  }
  if (read > 8)
    return -1;

  if ((total &= (len_mask - 1)) == len_mask - 1)
    num_ffs++;
  if (size < read)
    return -1;
  while (n < read) {
    if (data[n] == 0xff)
      num_ffs++;
    total = (total << 8) | data[n];
    n++;
  }

  if (read == num_ffs && total != 0)
    *num = G_MAXUINT64;
  else
    *num = total;

  return read;
}

static gint
gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
{
  guint64 unum;
  gint res;

  /* read as unsigned number first */
  if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
    return -1;

  /* make signed */
  if (unum == G_MAXUINT64)
    *num = G_MAXINT64;
  else
    *num = unum - ((1 << ((7 * res) - 1)) - 1);

  return res;
}

static GstFlowReturn
gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
    GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
    gboolean is_simpleblock)
{
  GstMatroskaTrackContext *stream = NULL;
  GstFlowReturn ret = GST_FLOW_OK;
  gboolean readblock = FALSE;
  guint32 id;
  guint64 block_duration = 0;
  GstBuffer *buf = NULL;
  GstMapInfo map;
  gint stream_num = -1, n, laces = 0;
  guint size = 0;
  gint *lace_size = NULL;
  gint64 time = 0;
  gint flags = 0;
  gint64 referenceblock = 0;

  while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
    if (!is_simpleblock) {
      if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
        goto data_error;
      }
    } else {
      id = GST_MATROSKA_ID_SIMPLEBLOCK;
    }

    switch (id) {
        /* one block inside the group. Note, block parsing is one
         * of the harder things, so this code is a bit complicated.
         * See http://www.matroska.org/ for documentation. */
      case GST_MATROSKA_ID_SIMPLEBLOCK:
      case GST_MATROSKA_ID_BLOCK:
      {
        guint64 num;
        guint8 *data;

        if (buf) {
          gst_buffer_unref (buf);
          buf = NULL;
        }
        if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
          break;

        gst_buffer_map (buf, &map, GST_MAP_READ);
        data = map.data;
        size = map.size;

        /* first byte(s): blocknum */
        if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
          goto data_error;
        data += n;
        size -= n;

        /* fetch stream from num */
        stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
            num);
        if (G_UNLIKELY (size < 3)) {
          GST_WARNING_OBJECT (parse, "Invalid size %u", size);
          /* non-fatal, try next block(group) */
          ret = GST_FLOW_OK;
          goto done;
        } else if (G_UNLIKELY (stream_num < 0 ||
                stream_num >= parse->common.num_streams)) {
          /* let's not give up on a stray invalid track number */
          GST_WARNING_OBJECT (parse,
              "Invalid stream %d for track number %" G_GUINT64_FORMAT
              "; ignoring block", stream_num, num);
          goto done;
        }

        stream = g_ptr_array_index (parse->common.src, stream_num);

        /* time (relative to cluster time) */
        time = ((gint16) GST_READ_UINT16_BE (data));
        data += 2;
        size -= 2;
        flags = GST_READ_UINT8 (data);
        data += 1;
        size -= 1;

        GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
            flags);

        switch ((flags & 0x06) >> 1) {
          case 0x0:            /* no lacing */
            laces = 1;
            lace_size = g_new (gint, 1);
            lace_size[0] = size;
            break;

          case 0x1:            /* xiph lacing */
          case 0x2:            /* fixed-size lacing */
          case 0x3:            /* EBML lacing */
            if (size == 0)
              goto invalid_lacing;
            laces = GST_READ_UINT8 (data) + 1;
            data += 1;
            size -= 1;
            lace_size = g_new0 (gint, laces);

            switch ((flags & 0x06) >> 1) {
              case 0x1:        /* xiph lacing */  {
                guint temp, total = 0;

                for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
                  while (1) {
                    if (size == 0)
                      goto invalid_lacing;
                    temp = GST_READ_UINT8 (data);
                    lace_size[n] += temp;
                    data += 1;
                    size -= 1;
                    if (temp != 0xff)
                      break;
                  }
                  total += lace_size[n];
                }
                lace_size[n] = size - total;
                break;
              }

              case 0x2:        /* fixed-size lacing */
                for (n = 0; n < laces; n++)
                  lace_size[n] = size / laces;
                break;

              case 0x3:        /* EBML lacing */  {
                guint total;

                if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
                  goto data_error;
                data += n;
                size -= n;
                total = lace_size[0] = num;
                for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
                  gint64 snum;
                  gint r;

                  if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
                    goto data_error;
                  data += r;
                  size -= r;
                  lace_size[n] = lace_size[n - 1] + snum;
                  total += lace_size[n];
                }
                if (n < laces)
                  lace_size[n] = size - total;
                break;
              }
            }
            break;
        }

        if (ret != GST_FLOW_OK)
          break;

        readblock = TRUE;
        break;
      }

      case GST_MATROSKA_ID_BLOCKDURATION:{
        ret = gst_ebml_read_uint (ebml, &id, &block_duration);
        GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
            block_duration);
        break;
      }

      case GST_MATROSKA_ID_REFERENCEBLOCK:{
        ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
        GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
            referenceblock);
        break;
      }

      case GST_MATROSKA_ID_CODECSTATE:{
        guint8 *data;
        guint64 data_len = 0;

        if ((ret =
                gst_ebml_read_binary (ebml, &id, &data,
                    &data_len)) != GST_FLOW_OK)
          break;

        if (G_UNLIKELY (stream == NULL)) {
          GST_WARNING_OBJECT (parse,
              "Unexpected CodecState subelement - ignoring");
          break;
        }

        g_free (stream->codec_state);
        stream->codec_state = data;
        stream->codec_state_size = data_len;

        break;
      }

      default:
        ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
            "BlockGroup", id);
        break;

      case GST_MATROSKA_ID_BLOCKVIRTUAL:
      case GST_MATROSKA_ID_BLOCKADDITIONS:
      case GST_MATROSKA_ID_REFERENCEPRIORITY:
      case GST_MATROSKA_ID_REFERENCEVIRTUAL:
      case GST_MATROSKA_ID_SLICES:
        GST_DEBUG_OBJECT (parse,
            "Skipping BlockGroup subelement 0x%x - ignoring", id);
        ret = gst_ebml_read_skip (ebml);
        break;
    }

    if (is_simpleblock)
      break;
  }

  /* reading a number or so could have failed */
  if (ret != GST_FLOW_OK)
    goto data_error;

  if (ret == GST_FLOW_OK && readblock) {
    guint64 duration = 0;
    gint64 lace_time = 0;
    gboolean delta_unit;

    stream = g_ptr_array_index (parse->common.src, stream_num);

    if (cluster_time != GST_CLOCK_TIME_NONE) {
      /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
       * Drop unless the lace contains timestamp 0? */
      if (time < 0 && (-time) > cluster_time) {
        lace_time = 0;
      } else {
        if (stream->timecodescale == 1.0)
          lace_time = (cluster_time + time) * parse->common.time_scale;
        else
          lace_time =
              gst_util_guint64_to_gdouble ((cluster_time + time) *
              parse->common.time_scale) * stream->timecodescale;
      }
    } else {
      lace_time = GST_CLOCK_TIME_NONE;
    }

    if (lace_time != GST_CLOCK_TIME_NONE) {
      parse->last_timestamp = lace_time;
    }
    /* need to refresh segment info ASAP */
    if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
      GstSegment segment;
      GST_DEBUG_OBJECT (parse,
          "generating segment starting at %" GST_TIME_FORMAT,
          GST_TIME_ARGS (lace_time));
      /* pretend we seeked here */
      gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
          GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
          GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
      /* now convey our segment notion downstream */
      segment = parse->common.segment;
      segment.position = segment.start;
      gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
      parse->need_newsegment = FALSE;
    }

    if (block_duration) {
      if (stream->timecodescale == 1.0)
        duration = gst_util_uint64_scale (block_duration,
            parse->common.time_scale, 1);
      else
        duration =
            gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
            (gst_util_uint64_scale (block_duration, parse->common.time_scale,
                    1)) * stream->timecodescale);
    } else if (stream->default_duration) {
      duration = stream->default_duration * laces;
    }
    /* else duration is diff between timecode of this and next block */

    /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
       a ReferenceBlock implies that this is not a keyframe. In either
       case, it only makes sense for video streams. */
    delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
        ((is_simpleblock && !(flags & 0x80)) || referenceblock);

    if (delta_unit && stream->set_discont) {
      /* When doing seeks or such, we need to restart on key frames or
       * decoders might choke. */
      GST_DEBUG_OBJECT (parse, "skipping delta unit");
      goto done;
    }

    for (n = 0; n < laces; n++) {
      if (G_UNLIKELY (lace_size[n] > size)) {
        GST_WARNING_OBJECT (parse, "Invalid lace size");
        break;
      }

      /* QoS for video track with an index. the assumption is that
         index entries point to keyframes, but if that is not true we
         will instad skip until the next keyframe. */
      if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
          stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
          stream->index_table && parse->common.segment.rate > 0.0) {
        GstMatroskaTrackVideoContext *videocontext =
            (GstMatroskaTrackVideoContext *) stream;
        GstClockTime earliest_time;
        GstClockTime earliest_stream_time;

        GST_OBJECT_LOCK (parse);
        earliest_time = videocontext->earliest_time;
        GST_OBJECT_UNLOCK (parse);
        earliest_stream_time = gst_segment_to_position (&parse->common.segment,
            GST_FORMAT_TIME, earliest_time);

        if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
            GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
            lace_time <= earliest_stream_time) {
          /* find index entry (keyframe) <= earliest_stream_time */
          GstMatroskaIndex *entry =
              gst_util_array_binary_search (stream->index_table->data,
              stream->index_table->len, sizeof (GstMatroskaIndex),
              (GCompareDataFunc) gst_matroska_index_seek_find,
              GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);

          /* if that entry (keyframe) is after the current the current
             buffer, we can skip pushing (and thus decoding) all
             buffers until that keyframe. */
          if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
              entry->time > lace_time) {
            GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
            stream->set_discont = TRUE;
            goto next_lace;
          }
        }
      }
#if 0
      sub = gst_buffer_create_sub (buf,
          GST_BUFFER_SIZE (buf) - size, lace_size[n]);
      GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);

      if (delta_unit)
        GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
      else
        GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);

      if (stream->encodings != NULL && stream->encodings->len > 0)
        sub = gst_matroska_decode_buffer (stream, sub);

      if (sub == NULL) {
        GST_WARNING_OBJECT (parse, "Decoding buffer failed");
        goto next_lace;
      }

      GST_BUFFER_TIMESTAMP (sub) = lace_time;

      if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
        GstClockTime last_stop_end;

        /* Check if this stream is after segment stop */
        if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
            lace_time >= parse->common.segment.stop) {
          GST_DEBUG_OBJECT (parse,
              "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
              GST_TIME_ARGS (parse->common.segment.stop));
          gst_buffer_unref (sub);
          goto eos;
        }
        if (offset >= stream->to_offset) {
          GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
              stream->index);
          gst_buffer_unref (sub);
          goto eos;
        }

        /* handle gaps, e.g. non-zero start-time, or an cue index entry
         * that landed us with timestamps not quite intended */
        if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
            parse->segment.rate > 0.0) {
          GstClockTimeDiff diff;

          /* only send newsegments with increasing start times,
           * otherwise if these go back and forth downstream (sinks) increase
           * accumulated time and running_time */
          diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
          if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
              (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
                  lace_time < parse->segment.stop)) {
            GST_DEBUG_OBJECT (parse,
                "Gap of %" G_GINT64_FORMAT " ns detected in"
                "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
                "Sending updated NEWSEGMENT events", diff,
                stream->index, GST_TIME_ARGS (stream->pos),
                GST_TIME_ARGS (lace_time));
            /* send newsegment events such that the gap is not accounted in
             * accum time, hence running_time */
            /* close ahead of gap */
            gst_matroska_parse_send_event (parse,
                gst_event_new_new_segment (TRUE, parse->segment.rate,
                    parse->segment.format, parse->segment.last_stop,
                    parse->segment.last_stop, parse->segment.last_stop));
            /* skip gap */
            gst_matroska_parse_send_event (parse,
                gst_event_new_new_segment (FALSE, parse->segment.rate,
                    parse->segment.format, lace_time, parse->segment.stop,
                    lace_time));
            /* align segment view with downstream,
             * prevents double-counting accum when closing segment */
            gst_segment_set_newsegment (&parse->segment, FALSE,
                parse->segment.rate, parse->segment.format, lace_time,
                parse->segment.stop, lace_time);
            parse->segment.last_stop = lace_time;
          }
        }

        if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
            || parse->segment.last_stop < lace_time) {
          parse->segment.last_stop = lace_time;
        }

        last_stop_end = lace_time;
        if (duration) {
          GST_BUFFER_DURATION (sub) = duration / laces;
          last_stop_end += GST_BUFFER_DURATION (sub);
        }

        if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
            parse->last_stop_end < last_stop_end)
          parse->last_stop_end = last_stop_end;

        if (parse->segment.duration == -1 ||
            parse->segment.duration < lace_time) {
          gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
              last_stop_end);
          gst_element_post_message (GST_ELEMENT_CAST (parse),
              gst_message_new_duration (GST_OBJECT_CAST (parse),
                  GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
        }
      }

      stream->pos = lace_time;

      gst_matroska_parse_sync_streams (parse);

      if (stream->set_discont) {
        GST_DEBUG_OBJECT (parse, "marking DISCONT");
        GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
        stream->set_discont = FALSE;
      }

      /* reverse playback book-keeping */
      if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
        stream->from_time = lace_time;
      if (stream->from_offset == -1)
        stream->from_offset = offset;

      GST_DEBUG_OBJECT (parse,
          "Pushing lace %d, data of size %d for stream %d, time=%"
          GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
          GST_BUFFER_SIZE (sub), stream_num,
          GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
          GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));

      if (parse->element_index) {
        if (stream->index_writer_id == -1)
          gst_index_get_writer_id (parse->element_index,
              GST_OBJECT (stream->pad), &stream->index_writer_id);

        GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
            G_GUINT64_FORMAT " for writer id %d",
            GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
            stream->index_writer_id);
        gst_index_add_association (parse->element_index,
            stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
                GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
            GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
            cluster_offset, NULL);
      }

      gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));

      /* Postprocess the buffers depending on the codec used */
      if (stream->postprocess_frame) {
        GST_LOG_OBJECT (parse, "running post process");
        ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
      }

      ret = gst_pad_push (stream->pad, sub);
      if (parse->segment.rate < 0) {
        if (lace_time > parse->segment.stop && ret == GST_FLOW_EOS) {
          /* In reverse playback we can get a GST_FLOW_EOS when
           * we are at the end of the segment, so we just need to jump
           * back to the previous section. */
          GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
          ret = GST_FLOW_OK;
        }
      }
      /* combine flows */
      ret = gst_matroska_parse_combine_flows (parse, stream, ret);
#endif

    next_lace:
      size -= lace_size[n];
      if (lace_time != GST_CLOCK_TIME_NONE && duration)
        lace_time += duration / laces;
      else
        lace_time = GST_CLOCK_TIME_NONE;
    }
  }

done:
  if (buf) {
    gst_buffer_unmap (buf, &map);
    gst_buffer_unref (buf);
  }
  g_free (lace_size);

  return ret;

  /* EXITS */
invalid_lacing:
  {
    GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
    /* non-fatal, try next block(group) */
    ret = GST_FLOW_OK;
    goto done;
  }
data_error:
  {
    GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
    /* non-fatal, try next block(group) */
    ret = GST_FLOW_OK;
    goto done;
  }
}

/* return FALSE if block(group) should be skipped (due to a seek) */
static inline gboolean
gst_matroska_parse_seek_block (GstMatroskaParse * parse)
{
  if (G_UNLIKELY (parse->seek_block)) {
    if (!(--parse->seek_block)) {
      return TRUE;
    } else {
      GST_LOG_OBJECT (parse, "should skip block due to seek");
      return FALSE;
    }
  } else {
    return TRUE;
  }
}

static GstFlowReturn
gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
    GstEbmlRead * ebml)
{
  GstFlowReturn ret;
  guint64 seek_pos = (guint64) - 1;
  guint32 seek_id = 0;
  guint32 id;

  DEBUG_ELEMENT_START (parse, ebml, "Seek");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (parse, ebml, "Seek", 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_SEEKID:
      {
        guint64 t;

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

        GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
        seek_id = t;
        break;
      }

      case GST_MATROSKA_ID_SEEKPOSITION:
      {
        guint64 t;

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

        if (t > G_MAXINT64) {
          GST_WARNING_OBJECT (parse,
              "Too large SeekPosition %" G_GUINT64_FORMAT, t);
          break;
        }

        GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
        seek_pos = t;
        break;
      }

      default:
        ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
            "SeekHead", id);
        break;
    }
  }

  if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
    return ret;

  if (!seek_id || seek_pos == (guint64) - 1) {
    GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
        G_GUINT64_FORMAT ")", seek_id, seek_pos);
    return GST_FLOW_OK;
  }

  switch (seek_id) {
    case GST_MATROSKA_ID_SEEKHEAD:
    {
    }
    case GST_MATROSKA_ID_CUES:
    case GST_MATROSKA_ID_TAGS:
    case GST_MATROSKA_ID_TRACKS:
    case GST_MATROSKA_ID_SEGMENTINFO:
    case GST_MATROSKA_ID_ATTACHMENTS:
    case GST_MATROSKA_ID_CHAPTERS:
    {
      guint64 length;

      /* remember */
      length = gst_matroska_read_common_get_length (&parse->common);

      if (length == (guint64) - 1) {
        GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
        break;
      }

      /* check for validity */
      if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
        GST_WARNING_OBJECT (parse,
            "SeekHead reference lies outside file!" " (%"
            G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
            G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
            length);
        break;
      }

      /* only pick up index location when streaming */
      if (seek_id == GST_MATROSKA_ID_CUES) {
        parse->index_offset = seek_pos + parse->common.ebml_segment_start;
        GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
            parse->index_offset);
      }
      break;
    }

    default:
      GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
      break;
  }
  DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);

  return ret;
}

static GstFlowReturn
gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint32 id;

  DEBUG_ELEMENT_START (parse, ebml, "SeekHead");

  if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
    DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", 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_SEEKENTRY:
      {
        ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
        /* Ignore EOS and errors here */
        if (ret != GST_FLOW_OK) {
          GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
          ret = GST_FLOW_OK;
        }
        break;
      }

      default:
        ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
            "SeekHead", id);
        break;
    }
  }

  DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);

  return ret;
}

#define GST_FLOW_OVERFLOW   GST_FLOW_CUSTOM_ERROR

#define MAX_BLOCK_SIZE (15 * 1024 * 1024)

static inline GstFlowReturn
gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
{
  if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
    /* only a few blocks are expected/allowed to be large,
     * and will be recursed into, whereas others will be read and must fit */
    /* fatal in streaming case, as we can't step over easily */
    GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
        ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
            "file might be corrupt.", bytes));
    return GST_FLOW_ERROR;
  } else {
    return GST_FLOW_OK;
  }
}

/* returns TRUE if we truely are in error state, and should give up */
static inline gboolean
gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
{
  gint64 pos;

  /* sigh, one last attempt above and beyond call of duty ...;
   * search for cluster mark following current pos */
  pos = parse->common.offset;
  GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
  if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
    /* did not work, give up */
    return TRUE;
  } else {
    GST_DEBUG_OBJECT (parse, "... found at  %" G_GUINT64_FORMAT, pos);
    /* try that position */
    parse->common.offset = pos;
    return FALSE;
  }
}

/* initializes @ebml with @bytes from input stream at current offset.
 * Returns EOS if insufficient available,
 * ERROR if too much was attempted to read. */
static inline GstFlowReturn
gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
    GstEbmlRead * ebml)
{
  GstBuffer *buffer = NULL;
  GstFlowReturn ret = GST_FLOW_OK;

  GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
      bytes);
  ret = gst_matroska_parse_check_read_size (parse, bytes);
  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    /* otherwise fatal */
    ret = GST_FLOW_ERROR;
    goto exit;
  }
  if (gst_adapter_available (parse->common.adapter) >= bytes)
    buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
  else
    ret = GST_FLOW_EOS;
  if (G_LIKELY (buffer)) {
    gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
        parse->common.offset);
    parse->common.offset += bytes;
  }
exit:
  return ret;
}

static void
gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
{
  GstQuery *query;
  gboolean seekable = FALSE;
  gint64 start = -1, stop = -1;

  query = gst_query_new_seeking (GST_FORMAT_BYTES);
  if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
    GST_DEBUG_OBJECT (parse, "seeking query failed");
    goto done;
  }

  gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);

  /* try harder to query upstream size if we didn't get it the first time */
  if (seekable && stop == -1) {
    GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
    gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
        &stop);
  }

  /* if upstream doesn't know the size, it's likely that it's not seekable in
   * practice even if it technically may be seekable */
  if (seekable && (start != 0 || stop <= start)) {
    GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
    seekable = FALSE;
  }

done:
  GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
      G_GUINT64_FORMAT ")", seekable, start, stop);
  parse->seekable = seekable;

  gst_query_unref (query);
}

#if 0
static GstFlowReturn
gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
{
  guint32 id;
  guint64 before_pos;
  guint64 length;
  guint needed;
  GstFlowReturn ret = GST_FLOW_OK;

  GST_WARNING_OBJECT (parse,
      "Found Cluster element before Tracks, searching Tracks");

  /* remember */
  before_pos = parse->common.offset;

  /* Search Tracks element */
  while (TRUE) {
    ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
        GST_ELEMENT_CAST (parse), &id, &length, &needed);
    if (ret != GST_FLOW_OK)
      break;

    if (id != GST_MATROSKA_ID_TRACKS) {
      /* we may be skipping large cluster here, so forego size check etc */
      /* ... but we can't skip undefined size; force error */
      if (length == G_MAXUINT64) {
        ret = gst_matroska_parse_check_read_size (parse, length);
        break;
      } else {
        parse->common.offset += needed;
        parse->offset += length;
      }
      continue;
    }

    /* will lead to track parsing ... */
    ret = gst_matroska_parse_parse_id (parse, id, length, needed);
    break;
  }

  /* seek back */
  parse->offset = before_pos;

  return ret;
}
#endif

#define GST_READ_CHECK(stmt)  \
G_STMT_START { \
  if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
    if (ret == GST_FLOW_OVERFLOW) { \
      ret = GST_FLOW_OK; \
    } \
    goto read_error; \
  } \
} G_STMT_END

static void
gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
    GstBuffer * buffer)
{
  if (parse->pushed_headers) {
    GST_WARNING_OBJECT (parse,
        "Accumulating headers, but headers are already pushed");
  }

  if (parse->streamheader) {
    parse->streamheader = gst_buffer_append (parse->streamheader,
        gst_buffer_ref (buffer));
  } else {
    parse->streamheader = gst_buffer_ref (buffer);
  }

  GST_DEBUG ("%" G_GSIZE_FORMAT, gst_buffer_get_size (parse->streamheader));
}

static GstFlowReturn
gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
    gboolean keyframe)
{
  GstFlowReturn ret = GST_FLOW_OK;

  if (!parse->pushed_headers) {
    GstCaps *caps;
    GstStructure *s;
    GValue streamheader = { 0 };
    GValue bufval = { 0 };
    GstBuffer *buf;

    caps = gst_pad_get_current_caps (parse->common.sinkpad);
    /* FIXME: could run typefinding over header and pick better default */
    if (caps == NULL)
      caps = gst_caps_new_empty_simple ("video/x-matroska");
    else
      caps = gst_caps_make_writable (caps);

    s = gst_caps_get_structure (caps, 0);
    g_value_init (&streamheader, GST_TYPE_ARRAY);
    g_value_init (&bufval, GST_TYPE_BUFFER);
    buf = gst_buffer_copy (parse->streamheader);
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
    gst_value_set_buffer (&bufval, buf);
    gst_buffer_unref (buf);
    gst_value_array_append_value (&streamheader, &bufval);
    g_value_unset (&bufval);
    gst_structure_set_value (s, "streamheader", &streamheader);
    g_value_unset (&streamheader);
    //gst_caps_replace (parse->caps, caps);
    gst_pad_set_caps (parse->srcpad, caps);

    if (parse->need_newsegment) {
      gst_pad_push_event (parse->srcpad,
          gst_event_new_segment (&parse->common.segment));
      parse->need_newsegment = FALSE;
    }

    buf = gst_buffer_copy (parse->streamheader);
    gst_caps_unref (caps);

    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);

    ret = gst_pad_push (parse->srcpad, buf);

    parse->pushed_headers = TRUE;
  }

  if (!keyframe) {
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
  } else {
    GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
  }
  if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
    parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
  } else {
    GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
  }
  ret = gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));

  return ret;
}

static GstFlowReturn
gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
    guint64 length, guint needed)
{
  GstEbmlRead ebml = { 0, };
  GstFlowReturn ret = GST_FLOW_OK;
  guint64 read;
  //GstBuffer *buffer;

  GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
      "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);

#if 0
  if (gst_adapter_available (parse->adapter) >= length + needed) {
    buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
    gst_pad_push (parse->srcpad, buffer);
  } else {
    ret = GST_FLOW_EOS;
  }
  //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));

  return ret;
#endif



  /* if we plan to read and parse this element, we need prefix (id + length)
   * and the contents */
  /* mind about overflow wrap-around when dealing with undefined size */
  read = length;
  if (G_LIKELY (length != G_MAXUINT64))
    read += needed;

  switch (parse->common.state) {
    case GST_MATROSKA_READ_STATE_START:
      switch (id) {
        case GST_EBML_ID_HEADER:
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
          if (ret != GST_FLOW_OK)
            goto parse_failed;
          parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
          gst_matroska_parse_check_seekability (parse);
          gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
          break;
        default:
          goto invalid_header;
          break;
      }
      break;
    case GST_MATROSKA_READ_STATE_SEGMENT:
      switch (id) {
        case GST_MATROSKA_ID_SEGMENT:
          /* eat segment prefix */
          GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
          GST_DEBUG_OBJECT (parse,
              "Found Segment start at offset %" G_GUINT64_FORMAT,
              parse->common.offset);
          /* seeks are from the beginning of the segment,
           * after the segment ID/length */
          parse->common.ebml_segment_start = parse->common.offset;
          parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
          gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
          break;
        default:
          GST_WARNING_OBJECT (parse,
              "Expected a Segment ID (0x%x), but received 0x%x!",
              GST_MATROSKA_ID_SEGMENT, id);
          GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
          gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
          break;
      }
      break;
    case GST_MATROSKA_READ_STATE_SCANNING:
      if (id != GST_MATROSKA_ID_CLUSTER &&
          id != GST_MATROSKA_ID_CLUSTERTIMECODE)
        goto skip;
      /* fall-through */
    case GST_MATROSKA_READ_STATE_HEADER:
    case GST_MATROSKA_READ_STATE_DATA:
    case GST_MATROSKA_READ_STATE_SEEK:
      switch (id) {
        case GST_MATROSKA_ID_SEGMENTINFO:
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          if (!parse->common.segmentinfo_parsed) {
            ret = gst_matroska_read_common_parse_info (&parse->common,
                GST_ELEMENT_CAST (parse), &ebml);
          }
          gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
          break;
        case GST_MATROSKA_ID_TRACKS:
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          if (!parse->tracks_parsed) {
            ret = gst_matroska_parse_parse_tracks (parse, &ebml);
          }
          gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
          break;
        case GST_MATROSKA_ID_CLUSTER:
          if (G_UNLIKELY (!parse->tracks_parsed)) {
            GST_DEBUG_OBJECT (parse, "Cluster before Track");
            goto not_streamable;
          }
          if (G_UNLIKELY (parse->common.state
                  == GST_MATROSKA_READ_STATE_HEADER)) {
            parse->common.state = GST_MATROSKA_READ_STATE_DATA;
            parse->first_cluster_offset = parse->common.offset;
            GST_DEBUG_OBJECT (parse, "signaling no more pads");
          }
          parse->cluster_time = GST_CLOCK_TIME_NONE;
          parse->cluster_offset = parse->common.offset;
          if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
            GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
                " not found in Cluster, trying next Cluster's first block instead",
                parse->seek_block);
            parse->seek_block = 0;
          }
          parse->seek_first = FALSE;
          /* record next cluster for recovery */
          if (read != G_MAXUINT64)
            parse->next_cluster_offset = parse->cluster_offset + read;
          /* eat cluster prefix */
          GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
          ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
          //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
          break;
        case GST_MATROSKA_ID_CLUSTERTIMECODE:
        {
          guint64 num;

          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
            goto parse_failed;
          GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
          parse->cluster_time = num;
#if 0
          if (parse->common.element_index) {
            if (parse->common.element_index_writer_id == -1)
              gst_index_get_writer_id (parse->common.element_index,
                  GST_OBJECT (parse), &parse->common.element_index_writer_id);
            GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
                G_GUINT64_FORMAT " for writer id %d",
                GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
                parse->common.element_index_writer_id);
            gst_index_add_association (parse->common.element_index,
                parse->common.element_index_writer_id,
                GST_ASSOCIATION_FLAG_KEY_UNIT,
                GST_FORMAT_TIME, parse->cluster_time,
                GST_FORMAT_BYTES, parse->cluster_offset, NULL);
          }
#endif
          gst_matroska_parse_output (parse, ebml.buf, FALSE);
          break;
        }
        case GST_MATROSKA_ID_BLOCKGROUP:
          if (!gst_matroska_parse_seek_block (parse))
            goto skip;
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
          if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
            ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
                &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
          }
          DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
          gst_matroska_parse_output (parse, ebml.buf, FALSE);
          break;
        case GST_MATROSKA_ID_SIMPLEBLOCK:
          if (!gst_matroska_parse_seek_block (parse))
            goto skip;
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
          ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
              &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
          DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
          gst_matroska_parse_output (parse, ebml.buf, FALSE);
          break;
        case GST_MATROSKA_ID_ATTACHMENTS:
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          if (!parse->common.attachments_parsed) {
            ret = gst_matroska_read_common_parse_attachments (&parse->common,
                GST_ELEMENT_CAST (parse), &ebml);
          }
          gst_matroska_parse_output (parse, ebml.buf, FALSE);
          break;
        case GST_MATROSKA_ID_TAGS:
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          ret = gst_matroska_read_common_parse_metadata (&parse->common,
              GST_ELEMENT_CAST (parse), &ebml);
          gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
          break;
        case GST_MATROSKA_ID_CHAPTERS:
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
          gst_matroska_parse_output (parse, ebml.buf, FALSE);
          break;
        case GST_MATROSKA_ID_SEEKHEAD:
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          ret = gst_matroska_parse_parse_contents (parse, &ebml);
          gst_matroska_parse_output (parse, ebml.buf, FALSE);
          break;
        case GST_MATROSKA_ID_CUES:
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          if (!parse->common.index_parsed) {
            ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
            /* only push based; delayed index building */
            if (ret == GST_FLOW_OK
                && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
              GstEvent *event;

              GST_OBJECT_LOCK (parse);
              event = parse->seek_event;
              parse->seek_event = NULL;
              GST_OBJECT_UNLOCK (parse);

              g_assert (event);
              /* unlikely to fail, since we managed to seek to this point */
              if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
                goto seek_failed;
              /* resume data handling, main thread clear to seek again */
              GST_OBJECT_LOCK (parse);
              parse->common.state = GST_MATROSKA_READ_STATE_DATA;
              GST_OBJECT_UNLOCK (parse);
            }
          }
          gst_matroska_parse_output (parse, ebml.buf, FALSE);
          break;
        case GST_MATROSKA_ID_POSITION:
        case GST_MATROSKA_ID_PREVSIZE:
        case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
        case GST_MATROSKA_ID_SILENTTRACKS:
          GST_DEBUG_OBJECT (parse,
              "Skipping Cluster subelement 0x%x - ignoring", id);
          /* fall-through */
        default:
        skip:
          GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
          GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
          gst_matroska_parse_output (parse, ebml.buf, FALSE);
          break;
      }
      break;
  }

  if (ret == GST_FLOW_PARSE)
    goto parse_failed;

exit:
  gst_ebml_read_clear (&ebml);
  return ret;

  /* ERRORS */
read_error:
  {
    /* simply exit, maybe not enough data yet */
    /* no ebml to clear if read error */
    return ret;
  }
parse_failed:
  {
    GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
        ("Failed to parse Element 0x%x", id));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
not_streamable:
  {
    GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
        ("File layout does not permit streaming"));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
#if 0
no_tracks:
  {
    GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
        ("No Tracks element found"));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
#endif
invalid_header:
  {
    GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
seek_failed:
  {
    GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
}

#if 0
static void
gst_matroska_parse_loop (GstPad * pad)
{
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
  GstFlowReturn ret;
  guint32 id;
  guint64 length;
  guint needed;

  /* If we have to close a segment, send a new segment to do this now */
  if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
    if (G_UNLIKELY (parse->close_segment)) {
      gst_matroska_parse_send_event (parse, parse->close_segment);
      parse->close_segment = NULL;
    }
    if (G_UNLIKELY (parse->new_segment)) {
      gst_matroska_parse_send_event (parse, parse->new_segment);
      parse->new_segment = NULL;
    }
  }

  ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
      GST_ELEMENT_CAST (parse), &id, &length, &needed);
  if (ret == GST_FLOW_EOS)
    goto eos;
  if (ret != GST_FLOW_OK) {
    if (gst_matroska_parse_check_parse_error (parse))
      goto pause;
    else
      return;
  }

  GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
      "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
      length, needed);

  ret = gst_matroska_parse_parse_id (parse, id, length, needed);
  if (ret == GST_FLOW_EOS)
    goto eos;
  if (ret != GST_FLOW_OK)
    goto pause;

  /* check if we're at the end of a configured segment */
  if (G_LIKELY (parse->src->len)) {
    guint i;

    g_assert (parse->num_streams == parse->src->len);
    for (i = 0; i < parse->src->len; i++) {
      GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
      GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
          GST_TIME_ARGS (context->pos));
      if (context->eos == FALSE)
        goto next;
    }

    GST_INFO_OBJECT (parse, "All streams are EOS");
    ret = GST_FLOW_EOS;
    goto eos;
  }

next:
  if (G_UNLIKELY (parse->offset ==
          gst_matroska_read_common_get_length (&parse->common))) {
    GST_LOG_OBJECT (parse, "Reached end of stream");
    ret = GST_FLOW_EOS;
    goto eos;
  }

  return;

  /* ERRORS */
eos:
  {
    if (parse->segment.rate < 0.0) {
      ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
      if (ret == GST_FLOW_OK)
        return;
    }
    /* fall-through */
  }
pause:
  {
    const gchar *reason = gst_flow_get_name (ret);
    gboolean push_eos = FALSE;

    GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
    parse->segment_running = FALSE;
    gst_pad_pause_task (parse->common.sinkpad);

    if (ret == GST_FLOW_EOS) {
      /* perform EOS logic */

      /* Close the segment, i.e. update segment stop with the duration
       * if no stop was set */
      if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
          !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
        GstEvent *event =
            gst_event_new_new_segment_full (TRUE, parse->segment.rate,
            parse->segment.applied_rate, parse->segment.format,
            parse->segment.start,
            MAX (parse->last_stop_end, parse->segment.start),
            parse->segment.time);
        gst_matroska_parse_send_event (parse, event);
      }

      if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
        gint64 stop;

        /* for segment playback we need to post when (in stream time)
         * we stopped, this is either stop (when set) or the duration. */
        if ((stop = parse->segment.stop) == -1)
          stop = parse->last_stop_end;

        GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
        gst_element_post_message (GST_ELEMENT (parse),
            gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
                stop));
        gst_matroska_parse_send_event (parse,
            gst_event_new_segment_done (GST_FORMAT_TIME, stop));
      } else {
        push_eos = TRUE;
      }
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
      /* for fatal errors we post an error message */
      GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL),
          ("stream stopped, reason %s", reason));
      push_eos = TRUE;
    }
    if (push_eos) {
      /* send EOS, and prevent hanging if no streams yet */
      GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
      if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
          (ret == GST_FLOW_EOS)) {
        GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
            (NULL), ("got eos but no streams (yet)"));
      }
    }
    return;
  }
}
#endif

/*
 * Create and push a flushing seek event upstream
 */
static gboolean
perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
{
  GstEvent *event;
  gboolean res = 0;

  GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);

  event =
      gst_event_new_seek (1.0, GST_FORMAT_BYTES,
      GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
      GST_SEEK_TYPE_NONE, -1);

  res = gst_pad_push_event (parse->common.sinkpad, event);

  /* newsegment event will update offset */
  return res;
}

static GstFlowReturn
gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
  guint available;
  GstFlowReturn ret = GST_FLOW_OK;
  guint needed = 0;
  guint32 id;
  guint64 length;

  if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
    GST_DEBUG_OBJECT (parse, "got DISCONT");
    gst_adapter_clear (parse->common.adapter);
    GST_OBJECT_LOCK (parse);
    gst_matroska_read_common_reset_streams (&parse->common,
        GST_CLOCK_TIME_NONE, FALSE);
    GST_OBJECT_UNLOCK (parse);
  }

  gst_adapter_push (parse->common.adapter, buffer);
  buffer = NULL;

next:
  available = gst_adapter_available (parse->common.adapter);

  ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
      GST_ELEMENT_CAST (parse), &id, &length, &needed);
  if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
    return ret;

  GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
      "size %" G_GUINT64_FORMAT ", needed %d, available %d",
      parse->common.offset, id, length, needed, available);

  if (needed > available)
    return GST_FLOW_OK;

  ret = gst_matroska_parse_parse_id (parse, id, length, needed);
  if (ret == GST_FLOW_EOS) {
    /* need more data */
    return GST_FLOW_OK;
  } else if (ret != GST_FLOW_OK) {
    return ret;
  } else
    goto next;
}

static gboolean
gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean res = TRUE;
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));

  GST_DEBUG_OBJECT (parse,
      "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      const GstSegment *segment;

      /* some debug output */
      gst_event_parse_segment (event, &segment);
      GST_DEBUG_OBJECT (parse,
          "received format %d newsegment %" GST_SEGMENT_FORMAT,
          segment->format, segment);

      if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
        GST_DEBUG_OBJECT (parse, "still starting");
        goto exit;
      }

      /* we only expect a BYTE segment, e.g. following a seek */
      if (segment->format != GST_FORMAT_BYTES) {
        GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
        goto exit;
      }

      GST_DEBUG_OBJECT (parse, "clearing segment state");
      /* clear current segment leftover */
      gst_adapter_clear (parse->common.adapter);
      /* and some streaming setup */
      parse->common.offset = segment->start;
      /* do not know where we are;
       * need to come across a cluster and generate newsegment */
      parse->common.segment.position = GST_CLOCK_TIME_NONE;
      parse->cluster_time = GST_CLOCK_TIME_NONE;
      parse->cluster_offset = 0;
      parse->need_newsegment = TRUE;
      /* but keep some of the upstream segment */
      parse->common.segment.rate = segment->rate;
    exit:
      /* chain will send initial newsegment after pads have been added,
       * or otherwise come up with one */
      GST_DEBUG_OBJECT (parse, "eating event");
      gst_event_unref (event);
      res = TRUE;
      break;
    }
    case GST_EVENT_EOS:
    {
      if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
        gst_event_unref (event);
        GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
            (NULL), ("got eos and didn't receive a complete header object"));
      } else if (parse->common.num_streams == 0) {
        GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
            (NULL), ("got eos but no streams (yet)"));
      } else {
        gst_matroska_parse_send_event (parse, event);
      }
      break;
    }
    case GST_EVENT_FLUSH_STOP:
    {
      gst_adapter_clear (parse->common.adapter);
      GST_OBJECT_LOCK (parse);
      gst_matroska_read_common_reset_streams (&parse->common,
          GST_CLOCK_TIME_NONE, TRUE);
      GST_OBJECT_UNLOCK (parse);
      parse->common.segment.position = GST_CLOCK_TIME_NONE;
      parse->cluster_time = GST_CLOCK_TIME_NONE;
      parse->cluster_offset = 0;
      /* fall-through */
    }
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

  return res;
}

#if 0
static void
gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
{
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);

  GST_OBJECT_LOCK (parse);
  if (parse->common.element_index)
    gst_object_unref (parse->common.element_index);
  parse->common.element_index = index ? gst_object_ref (index) : NULL;
  GST_OBJECT_UNLOCK (parse);
  GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
      parse->common.element_index);
}

static GstIndex *
gst_matroska_parse_get_index (GstElement * element)
{
  GstIndex *result = NULL;
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);

  GST_OBJECT_LOCK (parse);
  if (parse->common.element_index)
    result = gst_object_ref (parse->common.element_index);
  GST_OBJECT_UNLOCK (parse);

  GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);

  return result;
}
#endif

static GstStateChangeReturn
gst_matroska_parse_change_state (GstElement * element,
    GstStateChange transition)
{
  GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  /* handle upwards state changes here */
  switch (transition) {
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  /* handle downwards state changes */
  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_matroska_parse_reset (GST_ELEMENT (parse));
      break;
    default:
      break;
  }

  return ret;
}

gboolean
gst_matroska_parse_plugin_init (GstPlugin * plugin)
{
  gst_riff_init ();

  /* create an elementfactory for the matroska_parse element */
  if (!gst_element_register (plugin, "matroskaparse",
          GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))
    return FALSE;

  return TRUE;
}
