/* GStreamer
 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
 *
 * gstoggdemux.c: ogg stream demuxer
 *
 * 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.
 */

/**
 * SECTION:element-oggdemux
 * @title: oggdemux
 * @see_also: <link linkend="gst-plugins-base-plugins-oggmux">oggmux</link>
 *
 * This element demuxes ogg files into their encoded audio and video components.
 *
 * ## Example pipelines
 * |[
 * gst-launch-1.0 -v filesrc location=test.ogg ! oggdemux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
 * ]|
 *  Decodes a vorbis audio stream stored inside an ogg container and plays it.
 *
 */


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

#include <string.h>
#include <gst/gst-i18n-plugin.h>
#include <gst/tag/tag.h>
#include <gst/audio/audio.h>

#include "gstoggdemux.h"

#define CHUNKSIZE (8500)        /* this is out of vorbisfile */

/* we hope we get a granpos within this many bytes off the end */
#define DURATION_CHUNK_OFFSET (128*1024)

/* An Ogg page can not be larger than 255 segments of 255 bytes, plus
   26 bytes of header */
#define MAX_OGG_PAGE_SIZE (255 * 255 + 26)

#define GST_FLOW_LIMIT GST_FLOW_CUSTOM_ERROR
#define GST_FLOW_SKIP_PUSH GST_FLOW_CUSTOM_SUCCESS_1

#define SEEK_GIVE_UP_THRESHOLD (3*GST_SECOND)

#define GST_CHAIN_LOCK(ogg)     g_mutex_lock(&(ogg)->chain_lock)
#define GST_CHAIN_UNLOCK(ogg)   g_mutex_unlock(&(ogg)->chain_lock)

#define GST_PUSH_LOCK(ogg)                  \
  do {                                      \
    GST_TRACE_OBJECT(ogg, "Push lock");     \
    g_mutex_lock(&(ogg)->push_lock);        \
  } while(0)

#define GST_PUSH_UNLOCK(ogg)                \
  do {                                      \
    GST_TRACE_OBJECT(ogg, "Push unlock");   \
    g_mutex_unlock(&(ogg)->push_lock);      \
  } while(0)

GST_DEBUG_CATEGORY (gst_ogg_demux_debug);
GST_DEBUG_CATEGORY (gst_ogg_demux_setup_debug);
#define GST_CAT_DEFAULT gst_ogg_demux_debug


static ogg_packet *
_ogg_packet_copy (const ogg_packet * packet)
{
  ogg_packet *ret = g_slice_new (ogg_packet);

  *ret = *packet;
  ret->packet = g_memdup (packet->packet, packet->bytes);

  return ret;
}

static void
_ogg_packet_free (ogg_packet * packet)
{
  g_free (packet->packet);
  g_slice_free (ogg_packet, packet);
}

static ogg_page *
gst_ogg_page_copy (ogg_page * page)
{
  ogg_page *p = g_slice_new (ogg_page);

  /* make a copy of the page */
  p->header = g_memdup (page->header, page->header_len);
  p->header_len = page->header_len;
  p->body = g_memdup (page->body, page->body_len);
  p->body_len = page->body_len;

  return p;
}

static void
gst_ogg_page_free (ogg_page * page)
{
  g_free (page->header);
  g_free (page->body);
  g_slice_free (ogg_page, page);
}

static gboolean gst_ogg_demux_collect_chain_info (GstOggDemux * ogg,
    GstOggChain * chain);
static gboolean gst_ogg_demux_activate_chain (GstOggDemux * ogg,
    GstOggChain * chain, GstEvent * event);
static void gst_ogg_pad_mark_discont (GstOggPad * pad);
static void gst_ogg_chain_mark_discont (GstOggChain * chain);

static gboolean gst_ogg_demux_perform_seek (GstOggDemux * ogg,
    GstEvent * event);
static gboolean gst_ogg_demux_receive_event (GstElement * element,
    GstEvent * event);

static void gst_ogg_pad_dispose (GObject * object);
static void gst_ogg_pad_finalize (GObject * object);

static gboolean gst_ogg_pad_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_ogg_pad_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstOggPad *gst_ogg_chain_get_stream (GstOggChain * chain,
    guint32 serialno);

static GstFlowReturn gst_ogg_demux_combine_flows (GstOggDemux * ogg,
    GstOggPad * pad, GstFlowReturn ret);
static void gst_ogg_demux_sync_streams (GstOggDemux * ogg);

static GstCaps *gst_ogg_demux_set_header_on_caps (GstOggDemux * ogg,
    GstCaps * caps, GList * headers);
static gboolean gst_ogg_demux_send_event (GstOggDemux * ogg, GstEvent * event);
static gboolean gst_ogg_demux_perform_seek_push (GstOggDemux * ogg,
    GstEvent * event);
static gboolean gst_ogg_demux_check_duration_push (GstOggDemux * ogg,
    GstSeekFlags flags, GstEvent * event);

GType gst_ogg_pad_get_type (void);
G_DEFINE_TYPE (GstOggPad, gst_ogg_pad, GST_TYPE_PAD);

static void
gst_ogg_pad_class_init (GstOggPadClass * klass)
{
  GObjectClass *gobject_class;

  gobject_class = (GObjectClass *) klass;

  gobject_class->dispose = gst_ogg_pad_dispose;
  gobject_class->finalize = gst_ogg_pad_finalize;
}

static void
gst_ogg_pad_init (GstOggPad * pad)
{
  gst_pad_set_event_function (GST_PAD (pad),
      GST_DEBUG_FUNCPTR (gst_ogg_pad_event));
  gst_pad_set_query_function (GST_PAD (pad),
      GST_DEBUG_FUNCPTR (gst_ogg_pad_src_query));
  gst_pad_use_fixed_caps (GST_PAD (pad));

  pad->current_granule = -1;
  pad->prev_granule = -1;
  pad->keyframe_granule = -1;

  pad->start_time = GST_CLOCK_TIME_NONE;

  pad->position = GST_CLOCK_TIME_NONE;

  pad->have_type = FALSE;
  pad->continued = NULL;
  pad->map.headers = NULL;
  pad->map.queued = NULL;

  pad->map.granulerate_n = 0;
  pad->map.granulerate_d = 0;
  pad->map.granuleshift = -1;
}

static void
gst_ogg_pad_dispose (GObject * object)
{
  GstOggPad *pad = GST_OGG_PAD (object);

  pad->chain = NULL;
  pad->ogg = NULL;

  g_list_foreach (pad->map.headers, (GFunc) _ogg_packet_free, NULL);
  g_list_free (pad->map.headers);
  pad->map.headers = NULL;
  g_list_foreach (pad->map.queued, (GFunc) _ogg_packet_free, NULL);
  g_list_free (pad->map.queued);
  pad->map.queued = NULL;

  g_free (pad->map.index);
  pad->map.index = NULL;

  /* clear continued pages */
  g_list_foreach (pad->continued, (GFunc) gst_ogg_page_free, NULL);
  g_list_free (pad->continued);
  pad->continued = NULL;

  if (pad->map.caps) {
    gst_caps_unref (pad->map.caps);
    pad->map.caps = NULL;
  }

  if (pad->map.taglist) {
    gst_tag_list_unref (pad->map.taglist);
    pad->map.taglist = NULL;
  }

  ogg_stream_reset (&pad->map.stream);

  G_OBJECT_CLASS (gst_ogg_pad_parent_class)->dispose (object);
}

static void
gst_ogg_pad_finalize (GObject * object)
{
  GstOggPad *pad = GST_OGG_PAD (object);

  ogg_stream_clear (&pad->map.stream);

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

static gboolean
gst_ogg_pad_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res = TRUE;
  GstOggDemux *ogg;

  ogg = GST_OGG_DEMUX (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
    {
      GstFormat format;
      gint64 total_time = -1;

      gst_query_parse_duration (query, &format, NULL);
      /* can only get duration in time */
      if (format != GST_FORMAT_TIME)
        goto wrong_format;

      if (ogg->total_time != -1) {
        /* we can return the total length */
        total_time = ogg->total_time;
      } else {
        gint bitrate = ogg->bitrate;

        /* try with length and bitrate */
        if (bitrate > 0) {
          GstQuery *uquery;

          /* ask upstream for total length in bytes */
          uquery = gst_query_new_duration (GST_FORMAT_BYTES);
          if (gst_pad_peer_query (ogg->sinkpad, uquery)) {
            gint64 length;

            gst_query_parse_duration (uquery, NULL, &length);

            /* estimate using the bitrate */
            total_time =
                gst_util_uint64_scale (length, 8 * GST_SECOND, bitrate);

            GST_LOG_OBJECT (ogg,
                "length: %" G_GINT64_FORMAT ", bitrate %d, total_time %"
                GST_TIME_FORMAT, length, bitrate, GST_TIME_ARGS (total_time));
          }
          gst_query_unref (uquery);
        }
      }

      gst_query_set_duration (query, GST_FORMAT_TIME, total_time);
      break;
    }
    case GST_QUERY_SEEKING:
    {
      GstFormat format;

      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      if (format == GST_FORMAT_TIME) {
        gboolean seekable = FALSE;
        gint64 stop = -1;

        GST_CHAIN_LOCK (ogg);
        if (ogg->pullmode) {
          seekable = TRUE;
          stop = ogg->total_time;
        } else if (ogg->push_disable_seeking) {
          seekable = FALSE;
        } else if (ogg->current_chain == NULL) {
          GstQuery *squery;

          /* assume we can seek if upstream is seekable in BYTES format */
          GST_LOG_OBJECT (ogg, "no current chain, check upstream seekability");
          squery = gst_query_new_seeking (GST_FORMAT_BYTES);
          if (gst_pad_peer_query (ogg->sinkpad, squery))
            gst_query_parse_seeking (squery, NULL, &seekable, NULL, NULL);
          else
            seekable = FALSE;
          gst_query_unref (squery);
        } else if (ogg->current_chain->streams->len) {
          gint i;

          seekable = FALSE;
          for (i = 0; i < ogg->current_chain->streams->len; i++) {
            GstOggPad *pad =
                g_array_index (ogg->current_chain->streams, GstOggPad *, i);

            seekable = TRUE;
            if (pad->map.index != NULL && pad->map.n_index != 0) {
              GstOggIndex *idx;
              GstClockTime idx_time;

              idx = &pad->map.index[pad->map.n_index - 1];
              idx_time =
                  gst_util_uint64_scale (idx->timestamp, GST_SECOND,
                  pad->map.kp_denom);
              if (stop == -1)
                stop = idx_time;
              else
                stop = MAX (idx_time, stop);
            } else {
              stop = ogg->push_time_length;
              if (stop == -1)
                stop = ogg->total_time;
            }
          }
        }

        gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0, stop);
        GST_CHAIN_UNLOCK (ogg);
      } else {
        res = FALSE;
      }
      break;
    }
    case GST_QUERY_SEGMENT:{
      GstFormat format;
      gint64 start, stop;

      format = ogg->segment.format;

      start =
          gst_segment_to_stream_time (&ogg->segment, format,
          ogg->segment.start);
      if ((stop = ogg->segment.stop) == -1)
        stop = ogg->segment.duration;
      else
        stop = gst_segment_to_stream_time (&ogg->segment, format, stop);

      gst_query_set_segment (query, ogg->segment.rate, format, start, stop);
      res = TRUE;
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
done:

  return res;

  /* ERRORS */
wrong_format:
  {
    GST_DEBUG_OBJECT (ogg, "only query duration on TIME is supported");
    res = FALSE;
    goto done;
  }
}

static gboolean
gst_ogg_demux_receive_event (GstElement * element, GstEvent * event)
{
  gboolean res;
  GstOggDemux *ogg;

  ogg = GST_OGG_DEMUX (element);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      /* now do the seek */
      res = gst_ogg_demux_perform_seek (ogg, event);
      gst_event_unref (event);
      break;
    default:
      GST_DEBUG_OBJECT (ogg, "We only handle seek events here");
      goto error;
  }

  return res;

  /* ERRORS */
error:
  {
    GST_DEBUG_OBJECT (ogg, "error handling event");
    gst_event_unref (event);
    return FALSE;
  }
}

static gboolean
gst_ogg_pad_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstOggDemux *ogg;

  ogg = GST_OGG_DEMUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      /* now do the seek */
      res = gst_ogg_demux_perform_seek (ogg, event);
      gst_event_unref (event);
      break;
    case GST_EVENT_RECONFIGURE:
      GST_OGG_PAD (pad)->last_ret = GST_FLOW_OK;
      res = gst_pad_event_default (pad, parent, event);
      break;
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

  return res;
}

static void
gst_ogg_pad_reset (GstOggPad * pad)
{
  ogg_stream_reset (&pad->map.stream);

  GST_DEBUG_OBJECT (pad, "doing reset");

  /* clear continued pages */
  g_list_foreach (pad->continued, (GFunc) gst_ogg_page_free, NULL);
  g_list_free (pad->continued);
  pad->continued = NULL;

  pad->last_ret = GST_FLOW_OK;
  pad->position = GST_CLOCK_TIME_NONE;
  pad->current_granule = -1;
  pad->prev_granule = -1;
  pad->keyframe_granule = -1;
  pad->is_eos = FALSE;
}

/* queue data, basically takes the packet, puts it in a buffer and store the
 * buffer in the queued list.  */
static GstFlowReturn
gst_ogg_demux_queue_data (GstOggPad * pad, ogg_packet * packet)
{
#ifndef GST_DISABLE_GST_DEBUG
  GstOggDemux *ogg = pad->ogg;
#endif

  GST_DEBUG_OBJECT (ogg, "%p queueing data serial %08x",
      pad, pad->map.serialno);

  pad->map.queued = g_list_append (pad->map.queued, _ogg_packet_copy (packet));

  /* we are ok now */
  return GST_FLOW_OK;
}

static GstFlowReturn
gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
    gboolean push_headers)
{
  GstBuffer *buf = NULL;
  GstFlowReturn ret, cret;
  GstOggDemux *ogg = pad->ogg;
  gint64 current_time;
  GstOggChain *chain;
  gint64 duration;
  gint offset;
  gint trim;
  GstClockTime out_timestamp, out_duration;
  guint64 out_offset, out_offset_end;
  gboolean delta_unit = FALSE;
  gboolean is_header;
  guint64 clip_start = 0, clip_end = 0;

  ret = cret = GST_FLOW_OK;
  GST_DEBUG_OBJECT (pad, "Chaining %d %d %" GST_TIME_FORMAT " %d %p",
      ogg->pullmode, ogg->push_state, GST_TIME_ARGS (ogg->push_time_length),
      ogg->push_disable_seeking, ogg->building_chain);

  if (G_UNLIKELY (pad->is_eos)) {
    GST_DEBUG_OBJECT (pad, "Skipping packet on pad that is eos");
    ret = GST_FLOW_EOS;
    goto combine;
  }

  GST_PUSH_LOCK (ogg);
  if (!ogg->pullmode && ogg->push_state == PUSH_PLAYING
      && ogg->push_time_length == GST_CLOCK_TIME_NONE
      && !ogg->push_disable_seeking) {
    if (!ogg->building_chain) {
      /* we got all headers, now try to get duration */
      if (!gst_ogg_demux_check_duration_push (ogg, GST_SEEK_FLAG_FLUSH, NULL)) {
        GST_PUSH_UNLOCK (ogg);
        return GST_FLOW_OK;
      }
    }
    GST_PUSH_UNLOCK (ogg);
    return GST_FLOW_OK;
  }
  GST_PUSH_UNLOCK (ogg);

  GST_DEBUG_OBJECT (ogg,
      "%p streaming to peer serial %08x", pad, pad->map.serialno);

  gst_ogg_stream_update_stats (&pad->map, packet);

  if (pad->map.is_ogm) {
    const guint8 *data;
    long bytes;

    data = packet->packet;
    bytes = packet->bytes;

    if (bytes < 1)
      goto empty_packet;

    if ((data[0] & 1) || (data[0] & 3 && pad->map.is_ogm_text)) {
      /* We don't push header packets for OGM */
      goto done;
    }

    offset = 1 + (((data[0] & 0xc0) >> 6) | ((data[0] & 0x02) << 1));
    delta_unit = (((data[0] & 0x08) >> 3) == 0);

    trim = 0;

    /* Strip trailing \0 for subtitles */
    if (pad->map.is_ogm_text) {
      while (bytes && data[bytes - 1] == 0) {
        trim++;
        bytes--;
      }
    }
  } else if (pad->map.is_vp8) {
    if ((packet->bytes >= 7 && memcmp (packet->packet, "OVP80\2 ", 7) == 0) ||
        packet->b_o_s ||
        (packet->bytes >= 5 && memcmp (packet->packet, "OVP80", 5) == 0)) {
      /* We don't push header packets for VP8 */
      goto done;
    }
    offset = 0;
    trim = 0;
    delta_unit = !gst_ogg_stream_packet_is_key_frame (&pad->map, packet);
  } else {
    offset = 0;
    trim = 0;
    delta_unit = !gst_ogg_stream_packet_is_key_frame (&pad->map, packet);
  }

  /* get timing info for the packet */
  is_header = gst_ogg_stream_packet_is_header (&pad->map, packet);
  if (is_header) {
    duration = 0;
    GST_DEBUG_OBJECT (ogg, "packet is header");
  } else {
    duration = gst_ogg_stream_get_packet_duration (&pad->map, packet);
    GST_DEBUG_OBJECT (ogg, "packet duration %" G_GUINT64_FORMAT, duration);
  }


  /* If we get a hole at start, it might be we're catching a stream
   * partway through. In that case, if the stream has an index, the
   * index might be mooted. However, as it's totally valid to index
   * a stream with a hole at start (ie, capturing a live stream and
   * then index it), we now check whether the index references some
   * offset beyond the byte length (if known). If this is the case,
   * we can be reasonably sure we're getting a stream partway, with
   * its index being now useless since we don't know how many bytes
   * were skipped, preventing us from patching the index offsets to
   * match the hole size. */
  if (!is_header && ogg->check_index_overflow) {
    GstQuery *query;
    GstFormat format;
    int i;
    gint64 length;
    gboolean beyond;

    if (ogg->current_chain) {
      query = gst_query_new_duration (GST_FORMAT_BYTES);
      if (gst_pad_peer_query (ogg->sinkpad, query)) {
        gst_query_parse_duration (query, &format, &length);
        if (format == GST_FORMAT_BYTES && length >= 0) {
          for (i = 0; i < ogg->current_chain->streams->len; i++) {
            GstOggPad *ipad =
                g_array_index (ogg->current_chain->streams, GstOggPad *, i);
            if (!ipad->map.index)
              continue;
            beyond = ipad->map.n_index
                && ipad->map.index[ipad->map.n_index - 1].offset >= length;
            if (beyond) {
              GST_WARNING_OBJECT (pad, "Index offsets beyong byte length");
              if (ipad->discont) {
                /* hole - the index is most likely screwed up */
                GST_WARNING_OBJECT (ogg, "Discarding entire index");
                g_free (ipad->map.index);
                ipad->map.index = NULL;
                ipad->map.n_index = 0;
              } else {
                /* no hole - we can just clip the index if needed */
                GST_WARNING_OBJECT (ogg, "Clipping index");
                while (ipad->map.n_index > 0
                    && ipad->map.index[ipad->map.n_index - 1].offset >= length)
                  ipad->map.n_index--;
                if (ipad->map.n_index == 0) {
                  GST_WARNING_OBJECT (ogg, "The entire index was clipped");
                  g_free (ipad->map.index);
                  ipad->map.index = NULL;
                }
              }
              /* We can't trust the total time if the index goes beyond */
              ipad->map.total_time = -1;
            } else {
              /* use total time to update the total ogg time */
              if (ogg->total_time == -1) {
                ogg->total_time = ipad->map.total_time;
              } else if (ipad->map.total_time > 0) {
                ogg->total_time = MAX (ogg->total_time, ipad->map.total_time);
              }
            }
          }
        }
      }
      gst_query_unref (query);
    }
    ogg->check_index_overflow = FALSE;
  }

  if (packet->b_o_s) {
    out_timestamp = GST_CLOCK_TIME_NONE;
    out_duration = GST_CLOCK_TIME_NONE;
    out_offset = 0;
    out_offset_end = -1;
  } else {
    if (packet->granulepos > -1) {
      gint64 granule = gst_ogg_stream_granulepos_to_granule (&pad->map,
          packet->granulepos);
      if (granule < 0) {
        GST_ERROR_OBJECT (ogg,
            "granulepos %" G_GINT64_FORMAT " yielded granule %" G_GINT64_FORMAT,
            (gint64) packet->granulepos, (gint64) granule);
        return GST_FLOW_ERROR;
      }
      pad->current_granule = granule;
      pad->keyframe_granule =
          gst_ogg_stream_granulepos_to_key_granule (&pad->map,
          packet->granulepos);
      GST_DEBUG_OBJECT (ogg, "new granule %" G_GUINT64_FORMAT,
          pad->current_granule);
    } else if (pad->current_granule != -1) {
      pad->current_granule += duration;
      if (!delta_unit) {
        pad->keyframe_granule = pad->current_granule;
      }
      GST_DEBUG_OBJECT (ogg, "interpolating granule %" G_GUINT64_FORMAT,
          pad->current_granule);
    }

    if (ogg->segment.rate < 0.0 && pad->current_granule == -1) {
      /* negative rates, allow output of packets with no timestamp, let downstream reconstruct */
      out_timestamp = -1;
      out_duration = -1;
      out_offset = -1;
      out_offset_end = -1;
      pad->prev_granule = -1;
    } else {
      /* we only push buffers after we have a valid granule. This is done so that
       * we nicely skip packets without a timestamp after a seek. This is ok
       * because we base our seek on the packet after the page with the smaller
       * timestamp. */
      if (pad->current_granule == -1) {
        pad->prev_granule = -1;
        goto no_timestamp;
      }

      if (pad->map.is_ogm) {
        out_timestamp = gst_ogg_stream_granule_to_time (&pad->map,
            pad->current_granule);
        out_duration = gst_util_uint64_scale (duration,
            GST_SECOND * pad->map.granulerate_d, pad->map.granulerate_n);
      } else if (pad->map.is_sparse) {
        out_timestamp = gst_ogg_stream_granule_to_time (&pad->map,
            pad->current_granule);
        if (duration == GST_CLOCK_TIME_NONE) {
          out_duration = GST_CLOCK_TIME_NONE;
        } else {
          out_duration = gst_util_uint64_scale (duration,
              GST_SECOND * pad->map.granulerate_d, pad->map.granulerate_n);
        }
      } else {
        /* The last packet may be clipped. This will be represented
           by the last granule being smaller than what it would otherwise
           have been, had no content been clipped. In that case, we
           cannot calculate the PTS of the audio from the packet length
           and granule. */
        if (packet->e_o_s) {
          if (pad->prev_granule >= 0)
            out_timestamp = gst_ogg_stream_granule_to_time (&pad->map,
                pad->prev_granule);
          else
            out_timestamp = GST_CLOCK_TIME_NONE;

          if (pad->map.audio_clipping
              && pad->current_granule < pad->prev_granule + duration) {
            clip_end = pad->prev_granule + duration - pad->current_granule;
          }
          if (pad->map.audio_clipping
              && pad->current_granule - duration < -pad->map.granule_offset) {
            if (pad->current_granule >= -pad->map.granule_offset) {
              guint64 already_removed =
                  pad->current_granule >
                  duration ? pad->current_granule - duration : 0;
              clip_start =
                  already_removed >
                  -pad->map.granule_offset ? 0 : -pad->map.granule_offset -
                  already_removed;
            } else
              clip_start = pad->current_granule;
          }
        } else {
          out_timestamp = gst_ogg_stream_granule_to_time (&pad->map,
              pad->current_granule - duration);

          if (pad->map.audio_clipping
              && pad->current_granule - duration < -pad->map.granule_offset) {
            if (pad->current_granule >= -pad->map.granule_offset) {
              guint64 already_removed =
                  pad->current_granule >
                  duration ? pad->current_granule - duration : 0;
              clip_start =
                  already_removed >
                  -pad->map.granule_offset ? 0 : -pad->map.granule_offset -
                  already_removed;
            } else
              clip_start = pad->current_granule;
          }
        }
        out_duration =
            gst_ogg_stream_granule_to_time (&pad->map,
            pad->current_granule) - out_timestamp;
      }
      out_offset_end =
          gst_ogg_stream_granule_to_granulepos (&pad->map,
          pad->current_granule, pad->keyframe_granule);
      out_offset =
          gst_ogg_stream_granule_to_time (&pad->map, pad->current_granule);
    }
    pad->prev_granule = pad->current_granule;
  }

  if (G_UNLIKELY (offset + trim > packet->bytes))
    goto invalid_packet;
  else if (pad->map.is_ogm_text) {
    /* check for invalid buffer sizes */
    if (G_UNLIKELY (offset + trim >= packet->bytes))
      goto empty_packet;
  }

  if (!pad->added)
    goto not_added;

  buf = gst_buffer_new_and_alloc (packet->bytes - offset - trim);

  if (pad->map.audio_clipping && (clip_start || clip_end)) {
    GST_DEBUG_OBJECT (pad,
        "Clipping %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT " (%"
        G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT ")", clip_start, clip_end,
        clip_start + clip_end, duration);
    gst_buffer_add_audio_clipping_meta (buf, GST_FORMAT_DEFAULT, clip_start,
        clip_end);
  }

  /* set delta flag for OGM content */
  if (delta_unit)
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);

  /* set header flag for buffers that are also in the streamheaders */
  if (is_header)
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);

  if (packet->packet != NULL) {
    /* copy packet in buffer */
    gst_buffer_fill (buf, 0, packet->packet + offset,
        packet->bytes - offset - trim);
  }

  GST_BUFFER_TIMESTAMP (buf) = out_timestamp;
  GST_BUFFER_DURATION (buf) = out_duration;
  GST_BUFFER_OFFSET (buf) = out_offset;
  GST_BUFFER_OFFSET_END (buf) = out_offset_end;

  /* Mark discont on the buffer */
  if (pad->discont) {
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    if (ogg->segment.rate < 0.0 || GST_BUFFER_TIMESTAMP_IS_VALID (buf))
      pad->discont = FALSE;
  }

  /* don't push the header packets when we are asked to skip them */
  if (!packet->b_o_s || push_headers) {
    if (pad->last_ret == GST_FLOW_OK) {
      GST_LOG_OBJECT (ogg, "Pushing buf %" GST_PTR_FORMAT, buf);
      ret = gst_pad_push (GST_PAD_CAST (pad), buf);
    } else {
      GST_DEBUG_OBJECT (ogg, "not pushing buffer on error pad");
      ret = pad->last_ret;
      gst_buffer_unref (buf);
    }
    buf = NULL;
  }

  /* we're done with skeleton stuff */
  if (pad->map.is_skeleton)
    goto combine;

  /* check if valid granulepos, then we can calculate the current
   * position. We know the granule for each packet but we only want to update
   * the position when we have a valid granulepos on the packet because else
   * our time jumps around for the different streams. */
  if (packet->granulepos < 0)
    goto combine;

  /* convert to time */
  current_time = gst_ogg_stream_get_end_time_for_granulepos (&pad->map,
      packet->granulepos);

  /* convert to stream time */
  if ((chain = pad->chain)) {
    gint64 chain_start = 0;

    if (chain->segment_start != GST_CLOCK_TIME_NONE)
      chain_start = chain->segment_start;

    current_time = current_time - chain_start + chain->begin_time;
  }

  /* and store as the current position */
  ogg->segment.position = current_time;

  GST_DEBUG_OBJECT (ogg, "ogg current time %" GST_TIME_FORMAT
      " (%" G_GINT64_FORMAT ")", GST_TIME_ARGS (current_time), current_time);

  pad->position = ogg->segment.position;

  /* check stream eos */
  if (!pad->is_eos && !delta_unit &&
      ((ogg->segment.rate > 0.0 &&
              ogg->segment.stop != GST_CLOCK_TIME_NONE &&
              current_time >= ogg->segment.stop) ||
          (ogg->segment.rate < 0.0 && current_time <= ogg->segment.start))) {
    GST_DEBUG_OBJECT (ogg, "marking pad %p EOS", pad);
    pad->is_eos = TRUE;

    if (ret == GST_FLOW_OK) {
      ret = GST_FLOW_EOS;
    }
  }

combine:
  /* combine flows */
  cret = gst_ogg_demux_combine_flows (ogg, pad, ret);

done:
  if (buf)
    gst_buffer_unref (buf);
  /* return combined flow result */
  return cret;

  /* special cases */
empty_packet:
  {
    GST_DEBUG_OBJECT (ogg, "Skipping empty packet");
    goto done;
  }

invalid_packet:
  {
    GST_DEBUG_OBJECT (ogg, "Skipping invalid packet");
    goto done;
  }

no_timestamp:
  {
    GST_DEBUG_OBJECT (ogg, "skipping packet: no valid granule found yet");
    goto done;
  }
not_added:
  {
    GST_DEBUG_OBJECT (ogg, "pad not added yet");
    goto done;
  }
}

static guint64
gst_ogg_demux_collect_start_time (GstOggDemux * ogg, GstOggChain * chain)
{
  gint i;
  guint64 start_time = G_MAXUINT64;

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

    if (pad->map.is_skeleton)
      continue;

    /*  can do this if the pad start time is not defined */
    GST_DEBUG_OBJECT (ogg, "Pad %08x (%s) start time is %" GST_TIME_FORMAT,
        pad->map.serialno, gst_ogg_stream_get_media_type (&pad->map),
        GST_TIME_ARGS (pad->start_time));
    if (pad->start_time == GST_CLOCK_TIME_NONE) {
      if (!pad->map.is_sparse) {
        start_time = G_MAXUINT64;
        break;
      }
    } else {
      start_time = MIN (start_time, pad->start_time);
    }
  }
  return start_time;
}

static GstClockTime
gst_ogg_demux_collect_sync_time (GstOggDemux * ogg, GstOggChain * chain)
{
  gint i;
  GstClockTime sync_time = GST_CLOCK_TIME_NONE;

  if (!chain) {
    GST_WARNING_OBJECT (ogg, "No chain!");
    return GST_CLOCK_TIME_NONE;
  }

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

    if (pad->map.is_sparse)
      continue;

    if (pad->push_sync_time == GST_CLOCK_TIME_NONE) {
      sync_time = GST_CLOCK_TIME_NONE;
      break;
    } else {
      if (sync_time == GST_CLOCK_TIME_NONE)
        sync_time = pad->push_sync_time;
      else
        sync_time = MAX (sync_time, pad->push_sync_time);
    }
  }
  return sync_time;
}

/* submit a packet to the oggpad, this function will run the type detection
 * code for the pad if this is the first packet for this stream
 */
static GstFlowReturn
gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
{
  gint64 granule;
  GstFlowReturn ret = GST_FLOW_OK;

  GstOggDemux *ogg = pad->ogg;

  GST_DEBUG_OBJECT (ogg, "%p submit packet serial %08x",
      pad, pad->map.serialno);

  if (!pad->have_type) {
    pad->have_type = gst_ogg_stream_setup_map (&pad->map, packet);
    if (!pad->have_type && !pad->map.caps) {
      pad->map.caps = gst_caps_new_empty_simple ("application/x-unknown");
    }
    if (pad->map.is_skeleton) {
      GST_DEBUG_OBJECT (ogg, "we have a fishead");
      /* copy values over to global ogg level */
      ogg->basetime = pad->map.basetime;
      ogg->prestime = pad->map.prestime;

      /* use total time to update the total ogg time */
      if (ogg->total_time == -1) {
        ogg->total_time = pad->map.total_time;
      } else if (pad->map.total_time > 0) {
        ogg->total_time = MAX (ogg->total_time, pad->map.total_time);
      }
    }
    if (!pad->map.caps) {
      GST_WARNING_OBJECT (ogg, "stream parser didn't create src pad caps");
    }
  }

  if (pad->map.is_skeleton) {
    guint32 serialno;
    GstOggPad *skel_pad;
    GstOggSkeleton type;

    /* try to parse the serialno first */
    if (gst_ogg_map_parse_fisbone (&pad->map, packet->packet, packet->bytes,
            &serialno, &type)) {

      GST_DEBUG_OBJECT (pad->ogg,
          "got skeleton packet for stream 0x%08x", serialno);

      skel_pad = gst_ogg_chain_get_stream (pad->chain, serialno);
      if (skel_pad) {
        switch (type) {
          case GST_OGG_SKELETON_FISBONE:
            /* parse the remainder of the fisbone in the pad with the serialno,
             * note that we ignore the start_time as this is usually wrong for
             * live streams */
            gst_ogg_map_add_fisbone (&skel_pad->map, &pad->map, packet->packet,
                packet->bytes, NULL);
            break;
          case GST_OGG_SKELETON_INDEX:
            gst_ogg_map_add_index (&skel_pad->map, &pad->map, packet->packet,
                packet->bytes);
            ogg->check_index_overflow = TRUE;
            break;
          default:
            break;
        }

      } else {
        GST_WARNING_OBJECT (pad->ogg,
            "found skeleton fisbone for an unknown stream 0x%08x", serialno);
      }
    }
  }

  GST_DEBUG_OBJECT (ogg, "%p packet has granulepos %" G_GINT64_FORMAT, pad,
      packet->granulepos);
  granule =
      gst_ogg_stream_granulepos_to_granule (&pad->map, packet->granulepos);
  if (granule > 0) {
    GST_DEBUG_OBJECT (ogg, "%p has granule %" G_GINT64_FORMAT, pad, granule);
    pad->current_granule = granule;
  } else if (granule == 0) {
    /* headers */
  } else if (granule != -1) {
    GST_ERROR_OBJECT (ogg,
        "granulepos %" G_GINT64_FORMAT " yielded granule %" G_GINT64_FORMAT,
        (gint64) packet->granulepos, (gint64) granule);
    return GST_FLOW_ERROR;
  }

  /* restart header packet count when seeing a b_o_s page;
   * particularly useful following a seek or even following chain finding */
  if (packet->b_o_s) {
    GST_DEBUG_OBJECT (ogg, "b_o_s packet, resetting header packet count");
    pad->map.n_header_packets_seen = 0;
    if (!pad->map.have_headers) {
      GST_DEBUG_OBJECT (ogg, "clearing header packets");
      g_list_foreach (pad->map.headers, (GFunc) _ogg_packet_free, NULL);
      g_list_free (pad->map.headers);
      pad->map.headers = NULL;
    }
  }

  /* Overload the value of b_o_s in ogg_packet with a flag whether or
   * not this is a header packet.  Maybe some day this could be cleaned
   * up.  */
  packet->b_o_s = gst_ogg_stream_packet_is_header (&pad->map, packet);
  if (!packet->b_o_s) {
    GST_DEBUG ("found non-header packet");
    pad->map.have_headers = TRUE;
    if (pad->start_time == GST_CLOCK_TIME_NONE) {
      gint64 duration = gst_ogg_stream_get_packet_duration (&pad->map, packet);
      GST_DEBUG ("duration %" G_GINT64_FORMAT, duration);
      if (duration != -1) {
        pad->map.accumulated_granule += duration;
        GST_DEBUG ("accumulated granule %" G_GINT64_FORMAT,
            pad->map.accumulated_granule);
      }

      if (packet->granulepos != -1) {
        ogg_int64_t start_granule;
        gint64 granule;

        granule = gst_ogg_stream_granulepos_to_granule (&pad->map,
            packet->granulepos);
        if (granule < 0) {
          GST_ERROR_OBJECT (ogg,
              "granulepos %" G_GINT64_FORMAT " yielded granule %"
              G_GINT64_FORMAT, (gint64) packet->granulepos, (gint64) granule);
          return GST_FLOW_ERROR;
        }

        if (granule >= pad->map.accumulated_granule)
          start_granule = granule - pad->map.accumulated_granule;
        else
          start_granule = 0;

        pad->start_time = gst_ogg_stream_granule_to_time (&pad->map,
            start_granule);
        GST_DEBUG_OBJECT (ogg,
            "start time %" GST_TIME_FORMAT " (%" GST_TIME_FORMAT ") for %s "
            "from granpos %" G_GINT64_FORMAT " (granule %" G_GINT64_FORMAT ", "
            "accumulated granule %" G_GINT64_FORMAT,
            GST_TIME_ARGS (pad->start_time), GST_TIME_ARGS (pad->start_time),
            gst_ogg_stream_get_media_type (&pad->map),
            (gint64) packet->granulepos, granule, pad->map.accumulated_granule);
      } else {
        packet->granulepos = gst_ogg_stream_granule_to_granulepos (&pad->map,
            pad->map.accumulated_granule + pad->current_granule,
            pad->keyframe_granule);
      }
    }
  } else {
    /* look for tags in header packet (before inc header count) */
    gst_ogg_stream_extract_tags (&pad->map, packet);
    pad->map.n_header_packets_seen++;
    if (!pad->map.have_headers) {
      pad->map.headers =
          g_list_append (pad->map.headers, _ogg_packet_copy (packet));
      GST_DEBUG ("keeping header packet %d", pad->map.n_header_packets_seen);
    }
  }

  /* we know the start_time of the pad data, see if we
   * can activate the complete chain if this is a dynamic
   * chain. We need all the headers too for this. */
  if (pad->start_time != GST_CLOCK_TIME_NONE && pad->map.have_headers) {
    GstOggChain *chain = pad->chain;

    /* check if complete chain has start time */
    if (chain == ogg->building_chain) {
      GstEvent *event = NULL;

      if (ogg->resync) {
        guint64 start_time;

        GST_DEBUG_OBJECT (ogg, "need to resync");

        /* when we need to resync after a seek, we wait until we have received
         * timestamps on all streams */
        start_time = gst_ogg_demux_collect_start_time (ogg, chain);

        if (start_time != G_MAXUINT64) {
          gint64 segment_time;
          GstSegment segment;

          GST_DEBUG_OBJECT (ogg, "start_time:  %" GST_TIME_FORMAT,
              GST_TIME_ARGS (start_time));

          if (chain->segment_start < start_time)
            segment_time =
                (start_time - chain->segment_start) + chain->begin_time;
          else
            segment_time = chain->begin_time;

          /* create the newsegment event we are going to send out */
          gst_segment_init (&segment, GST_FORMAT_TIME);

          GST_PUSH_LOCK (ogg);
          if (!ogg->pullmode && ogg->push_state == PUSH_LINEAR2) {
            /* if we are fast forwarding to the actual seek target,
               ensure previous frames are clipped */
            GST_DEBUG_OBJECT (ogg,
                "Resynced, starting segment at %" GST_TIME_FORMAT
                ", start_time %" GST_TIME_FORMAT,
                GST_TIME_ARGS (ogg->push_seek_time_original_target),
                GST_TIME_ARGS (start_time));
            segment.rate = ogg->push_seek_rate;
            segment.start = ogg->push_seek_time_original_target;
            segment.position = ogg->push_seek_time_original_target;
            segment.stop = ogg->push_seek_time_original_stop;
            segment.time = ogg->push_seek_time_original_target;
            segment.base = ogg->segment.base;
            event = gst_event_new_segment (&segment);
            ogg->push_state = PUSH_PLAYING;
          } else {
            segment.rate = ogg->segment.rate;
            segment.applied_rate = ogg->segment.applied_rate;
            segment.start = start_time;
            segment.position = start_time;
            segment.stop = chain->segment_stop;
            segment.time = segment_time;
            segment.base = ogg->segment.base;
            event = gst_event_new_segment (&segment);
          }
          GST_PUSH_UNLOCK (ogg);

          ogg->resync = FALSE;
        }
      } else {
        /* see if we have enough info to activate the chain, we have enough info
         * when all streams have a valid start time. */
        if (gst_ogg_demux_collect_chain_info (ogg, chain)) {
          GstSegment segment;

          GST_DEBUG_OBJECT (ogg, "segment_start: %" GST_TIME_FORMAT,
              GST_TIME_ARGS (chain->segment_start));
          GST_DEBUG_OBJECT (ogg, "segment_stop:  %" GST_TIME_FORMAT,
              GST_TIME_ARGS (chain->segment_stop));
          GST_DEBUG_OBJECT (ogg, "segment_time:  %" GST_TIME_FORMAT,
              GST_TIME_ARGS (chain->begin_time));

          /* create the newsegment event we are going to send out */
          gst_segment_init (&segment, GST_FORMAT_TIME);
          segment.rate = ogg->segment.rate;
          segment.applied_rate = ogg->segment.applied_rate;
          segment.start = chain->segment_start;
          segment.position = chain->segment_start;
          segment.stop = chain->segment_stop;
          segment.time = chain->begin_time;
          segment.base = ogg->segment.base + segment.time;
          event = gst_event_new_segment (&segment);
        }
      }

      if (event) {
        gst_event_set_seqnum (event, ogg->seqnum);

        gst_ogg_demux_activate_chain (ogg, chain, event);

        ogg->building_chain = NULL;
      }
    }
  }

  /* if we are building a chain, store buffer for when we activate
   * it. This path is taken if we operate in streaming mode. */
  if (ogg->building_chain) {
    /* bos packets where stored in the header list so we can discard
     * them here*/
    if (!packet->b_o_s)
      ret = gst_ogg_demux_queue_data (pad, packet);
  }
  /* else we are completely streaming to the peer */
  else {
    ret = gst_ogg_demux_chain_peer (pad, packet, !ogg->pullmode);
  }
  return ret;
}

/* flush at most @npackets from the stream layer. All packets if 
 * @npackets is 0;
 */
static GstFlowReturn
gst_ogg_pad_stream_out (GstOggPad * pad, gint npackets)
{
  GstFlowReturn result = GST_FLOW_OK;
  gboolean done = FALSE;
  GstOggDemux *ogg;

  ogg = pad->ogg;

  while (!done) {
    int ret;
    ogg_packet packet;

    ret = ogg_stream_packetout (&pad->map.stream, &packet);
    switch (ret) {
      case 0:
        GST_LOG_OBJECT (ogg, "packetout done");
        done = TRUE;
        break;
      case -1:
        GST_LOG_OBJECT (ogg, "packetout discont");
        if (!pad->map.is_sparse) {
          gst_ogg_chain_mark_discont (pad->chain);
        } else {
          gst_ogg_pad_mark_discont (pad);
        }
        break;
      case 1:
        GST_LOG_OBJECT (ogg, "packetout gave packet of size %ld", packet.bytes);

        if (packet.granulepos < -1) {
          GST_WARNING_OBJECT (ogg,
              "Invalid granulepos (%" G_GINT64_FORMAT "), resetting stream",
              packet.granulepos);
          gst_ogg_pad_reset (pad);
          break;
        }

        if (packet.bytes > ogg->max_packet_size)
          ogg->max_packet_size = packet.bytes;
        result = gst_ogg_pad_submit_packet (pad, &packet);
        /* not linked is not a problem, it's possible that we are still
         * collecting headers and that we don't have exposed the pads yet */
        if (result == GST_FLOW_NOT_LINKED)
          break;
        else if (result <= GST_FLOW_EOS)
          goto could_not_submit;
        break;
      default:
        GST_WARNING_OBJECT (ogg,
            "invalid return value %d for ogg_stream_packetout, resetting stream",
            ret);
        gst_ogg_pad_reset (pad);
        break;
    }
    if (npackets > 0) {
      npackets--;
      done = (npackets == 0);
    }
  }
  return result;

  /* ERRORS */
could_not_submit:
  {
    GST_WARNING_OBJECT (ogg,
        "could not submit packet for stream %08x, "
        "error: %d", pad->map.serialno, result);
    gst_ogg_pad_reset (pad);
    return result;
  }
}

static void
gst_ogg_demux_setup_first_granule (GstOggDemux * ogg, GstOggPad * pad,
    ogg_page * page)
{
  /* When we submit a page, we check if we have started tracking granules.
   * If not, we calculate the granule corresponding to the first packet
   * on the page. */
  gboolean valid_granule = TRUE;

  if (pad->current_granule == -1) {
    ogg_int64_t granpos = ogg_page_granulepos (page);
    if (granpos > 0) {
      gint64 granule =
          (gint64) gst_ogg_stream_granulepos_to_granule (&pad->map, granpos);
      gint64 duration;
      int packets = ogg_page_packets (page), n;
      GST_DEBUG_OBJECT (pad,
          "This page completes %d packets, granule %" G_GINT64_FORMAT, packets,
          granule);

      if (packets > 0) {
        ogg_stream_state os;
        ogg_packet op;
        int last_size = pad->map.last_size;

        memcpy (&os, &pad->map.stream, sizeof (os));
        for (n = 0; valid_granule && n < packets; ++n) {
          int ret = ogg_stream_packetout (&os, &op);
          if (ret < 0) {
            /* This usually means a continued packet after a seek and we can't calc the first granule,
             * but sometimes not - so if it's ret == -1 and first packet, try again */
            if (ret == -1 && n == 0) {
              n--;
              continue;
            }
            GST_DEBUG_OBJECT (pad, "Failed to read packet off first page");
            valid_granule = FALSE;
            break;
          }
          if (ret == 0) {
            GST_WARNING_OBJECT (pad,
                "Short read getting %d packets off first page", packets);
            valid_granule = FALSE;
            break;
          }
          duration = gst_ogg_stream_get_packet_duration (&pad->map, &op);
          GST_DEBUG_OBJECT (pad, "Packet %d has duration %" G_GINT64_FORMAT,
              n, duration);
          granule -= duration;
        }
        pad->map.last_size = last_size;
        if (valid_granule) {
          if (granule >= 0) {
            pad->current_granule = granule;
            GST_INFO_OBJECT (pad,
                "Starting with first granule %" G_GINT64_FORMAT, granule);
          } else {
            pad->current_granule = 0;
            GST_INFO_OBJECT (pad, "Extrapolated first granule is negative, "
                "used to clip samples at start");
          }
        }
      } else {
        GST_WARNING_OBJECT (pad,
            "Ogg page finishing no packets, but a valid granule");
      }
    }
  }
}

static void
gst_ogg_demux_setup_bisection_bounds (GstOggDemux * ogg)
{
  if (ogg->push_last_seek_time >= ogg->push_seek_time_target) {
    GST_DEBUG_OBJECT (ogg, "We overshot by %" GST_TIME_FORMAT,
        GST_TIME_ARGS (ogg->push_last_seek_time - ogg->push_seek_time_target));
    ogg->push_offset1 = ogg->push_last_seek_offset;
    ogg->push_time1 = ogg->push_last_seek_time;
    ogg->seek_undershot = FALSE;
  } else {
    GST_DEBUG_OBJECT (ogg, "We undershot by %" GST_TIME_FORMAT,
        GST_TIME_ARGS (ogg->push_seek_time_target - ogg->push_last_seek_time));
    ogg->push_offset0 = ogg->push_last_seek_offset;
    ogg->push_time0 = ogg->push_last_seek_time;
    ogg->seek_undershot = TRUE;
  }
}

static gint64
gst_ogg_demux_estimate_bisection_target (GstOggDemux * ogg, float seek_quality)
{
  gint64 best;
  gint64 segment_bitrate;
  gint64 skew;

  /* we might not know the length of the stream in time,
     so push_time1 might not be set */
  GST_DEBUG_OBJECT (ogg,
      "push time 1: %" GST_TIME_FORMAT ", dbytes %" G_GINT64_FORMAT,
      GST_TIME_ARGS (ogg->push_time1), ogg->push_offset1 - ogg->push_offset0);
  if (ogg->push_time1 == GST_CLOCK_TIME_NONE) {
    GST_DEBUG_OBJECT (ogg,
        "New segment to consider: bytes %" G_GINT64_FORMAT " %" G_GINT64_FORMAT
        ", time %" GST_TIME_FORMAT " (open ended)", ogg->push_offset0,
        ogg->push_offset1, GST_TIME_ARGS (ogg->push_time0));
    if (ogg->push_last_seek_time == ogg->push_start_time) {
      /* if we're at start and don't know the end time, we can't estimate
         bitrate, so get the nominal declared bitrate as a failsafe, or some
         random constant which will be discarded after we made a (probably
         dire) first guess */
      segment_bitrate = (ogg->bitrate > 0 ? ogg->bitrate : 1000);
    } else {
      segment_bitrate =
          gst_util_uint64_scale (ogg->push_last_seek_offset - 0,
          8 * GST_SECOND, ogg->push_last_seek_time - ogg->push_start_time);
    }
    best =
        ogg->push_offset0 +
        gst_util_uint64_scale (ogg->push_seek_time_target - ogg->push_time0,
        segment_bitrate, 8 * GST_SECOND);
    ogg->seek_secant = TRUE;
  } else {
    GST_DEBUG_OBJECT (ogg,
        "New segment to consider: bytes %" G_GINT64_FORMAT " %" G_GINT64_FORMAT
        ", time %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, ogg->push_offset0,
        ogg->push_offset1, GST_TIME_ARGS (ogg->push_time0),
        GST_TIME_ARGS (ogg->push_time1));
    if (ogg->push_time0 == ogg->push_time1) {
      best = ogg->push_offset0;
    } else {
      segment_bitrate =
          gst_util_uint64_scale (ogg->push_offset1 - ogg->push_offset0,
          8 * GST_SECOND, ogg->push_time1 - ogg->push_time0);
      GST_DEBUG_OBJECT (ogg,
          "Local bitrate on the %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT
          " segment: %" G_GINT64_FORMAT, GST_TIME_ARGS (ogg->push_time0),
          GST_TIME_ARGS (ogg->push_time1), segment_bitrate);

      best =
          ogg->push_offset0 +
          gst_util_uint64_scale (ogg->push_seek_time_target - ogg->push_time0,
          segment_bitrate, 8 * GST_SECOND);
      if (seek_quality < 0.5f && ogg->seek_secant) {
        gint64 new_best, best2 = (ogg->push_offset0 + ogg->push_offset1) / 2;
        /* if dire result, give as much as 25% weight to a dumb bisection guess */
        float secant_weight = 1.0f - ((0.5 - seek_quality) / 0.5f) * 0.25;
        new_best = (best * secant_weight + best2 * (1.0f - secant_weight));
        GST_DEBUG_OBJECT (ogg,
            "Secant says %" G_GINT64_FORMAT ", straight is %" G_GINT64_FORMAT
            ", new best %" G_GINT64_FORMAT " with secant_weight %f", best,
            best2, new_best, secant_weight);
        best = new_best;
        ogg->seek_secant = FALSE;
      } else {
        ogg->seek_secant = TRUE;
      }
    }
  }

  GST_DEBUG_OBJECT (ogg, "Raw best guess: %" G_GINT64_FORMAT, best);

  /* offset the guess down as we need to capture the start of the
     page we are targetting - but only do so if we did not undershoot
     last time, as we're likely to still do this time */
  if (!ogg->seek_undershot) {
    /* very small packets are packed on pages, so offset by at least
       a value which is likely to get us at least one page where the
       packet starts */
    skew =
        ogg->max_packet_size >
        ogg->max_page_size ? ogg->max_packet_size : ogg->max_page_size;
    GST_DEBUG_OBJECT (ogg, "Offsetting by %" G_GINT64_FORMAT, skew);
    best -= skew;
  }

  /* do not seek too close to the bounds, as we stop seeking
     when we get to within max_packet_size before the target */
  if (best > ogg->push_offset1 - ogg->max_packet_size) {
    best = ogg->push_offset1 - ogg->max_packet_size;
    GST_DEBUG_OBJECT (ogg,
        "Too close to high bound, pushing back to %" G_GINT64_FORMAT, best);
  } else if (best < ogg->push_offset0 + ogg->max_packet_size) {
    best = ogg->push_offset0 + ogg->max_packet_size;
    GST_DEBUG_OBJECT (ogg,
        "Too close to low bound, pushing forth to %" G_GINT64_FORMAT, best);
  }

  /* keep within bounds */
  if (best > ogg->push_offset1)
    best = ogg->push_offset1;
  if (best < ogg->push_offset0)
    best = ogg->push_offset0;

  GST_DEBUG_OBJECT (ogg, "Choosing target %" G_GINT64_FORMAT, best);
  return best;
}

static void
gst_ogg_demux_record_keyframe_time (GstOggDemux * ogg, GstOggPad * pad,
    ogg_int64_t granpos)
{
  gint64 kf_granule;
  GstClockTime kf_time;

  kf_granule = gst_ogg_stream_granulepos_to_key_granule (&pad->map, granpos);
  kf_time = gst_ogg_stream_granule_to_time (&pad->map, kf_granule);

  pad->push_kf_time = kf_time;
}

/* returns the earliest keyframe time for all non sparse pads in the chain,
 * if known, and GST_CLOCK_TIME_NONE if not */
static GstClockTime
gst_ogg_demux_get_earliest_keyframe_time (GstOggDemux * ogg)
{
  GstClockTime t = GST_CLOCK_TIME_NONE;
  GstOggChain *chain = ogg->building_chain;
  int i;

  if (!chain) {
    GST_WARNING_OBJECT (ogg, "No chain!");
    return GST_CLOCK_TIME_NONE;
  }
  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

    if (pad->map.is_sparse)
      continue;
    if (pad->push_kf_time == GST_CLOCK_TIME_NONE)
      return GST_CLOCK_TIME_NONE;
    if (t == GST_CLOCK_TIME_NONE || pad->push_kf_time < t)
      t = pad->push_kf_time;
  }

  return t;
}

/* MUST be called with the push lock locked, and will unlock it
   regardless of return value. */
static GstFlowReturn
gst_ogg_demux_seek_back_after_push_duration_check_unlock (GstOggDemux * ogg)
{
  GstEvent *event;

  /* Get the delayed event, if any */
  event = ogg->push_mode_seek_delayed_event;
  ogg->push_mode_seek_delayed_event = NULL;

  /* if we haven't learnt about the total time yet, disable seeking */
  if (ogg->total_time == -1)
    ogg->push_disable_seeking = TRUE;

  ogg->push_state = PUSH_PLAYING;

  /* If there is one, perform it. Otherwise, seek back at start to start
   * normal playback  */
  if (!event) {
    GST_INFO_OBJECT (ogg, "Seeking back to 0 after duration check");
    event = gst_event_new_seek (1.0, GST_FORMAT_BYTES,
        GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
        GST_SEEK_TYPE_SET, 1, GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE);
  }
  gst_event_replace (&ogg->seek_event, event);
  gst_event_unref (event);
  GST_PUSH_UNLOCK (ogg);
  g_mutex_lock (&ogg->seek_event_mutex);
  g_cond_broadcast (&ogg->seek_event_cond);
  g_mutex_unlock (&ogg->seek_event_mutex);

  return GST_FLOW_OK;
}

static float
gst_ogg_demux_estimate_seek_quality (GstOggDemux * ogg)
{
  GstClockTimeDiff diff;        /* how far from the goal we ended up */
  GstClockTimeDiff dist;        /* how far we moved this iteration */
  float seek_quality;

  if (ogg->push_prev_seek_time == GST_CLOCK_TIME_NONE) {
    /* for the first seek, we pretend we got a good seek,
       as we don't have a previous seek yet */
    return 1.0f;
  }

  /* We take a guess at how good the last seek was at guessing
     the byte target by comparing the amplitude of the last
     seek to the error */
  diff = GST_CLOCK_DIFF (ogg->push_seek_time_target, ogg->push_last_seek_time);
  if (diff < 0)
    diff = -diff;
  dist = GST_CLOCK_DIFF (ogg->push_last_seek_time, ogg->push_prev_seek_time);
  if (dist < 0)
    dist = -dist;

  seek_quality = (dist == 0) ? 0.0f : 1.0f / (1.0f + diff / (float) dist);

  GST_DEBUG_OBJECT (ogg,
      "We moved %" GST_STIME_FORMAT ", we're off by %" GST_STIME_FORMAT
      ", seek quality %f", GST_STIME_ARGS (dist), GST_STIME_ARGS (diff),
      seek_quality);
  return seek_quality;
}

static void
gst_ogg_demux_update_bisection_stats (GstOggDemux * ogg)
{
  int n;

  GST_INFO_OBJECT (ogg, "Bisection needed %d + %d steps",
      ogg->push_bisection_steps[0], ogg->push_bisection_steps[1]);

  for (n = 0; n < 2; ++n) {
    ogg->stats_bisection_steps[n] += ogg->push_bisection_steps[n];
    if (ogg->stats_bisection_max_steps[n] < ogg->push_bisection_steps[n])
      ogg->stats_bisection_max_steps[n] = ogg->push_bisection_steps[n];
  }
  ogg->stats_nbisections++;

  GST_INFO_OBJECT (ogg,
      "So far, %.2f + %.2f bisections needed per seek (max %d + %d)",
      ogg->stats_bisection_steps[0] / (float) ogg->stats_nbisections,
      ogg->stats_bisection_steps[1] / (float) ogg->stats_nbisections,
      ogg->stats_bisection_max_steps[0], ogg->stats_bisection_max_steps[1]);
}

static gboolean
gst_ogg_pad_handle_push_mode_state (GstOggPad * pad, ogg_page * page)
{
  GstOggDemux *ogg = pad->ogg;
  ogg_int64_t granpos = ogg_page_granulepos (page);

  GST_PUSH_LOCK (ogg);
  if (granpos >= 0 && pad->have_type) {
    if (ogg->push_start_time == GST_CLOCK_TIME_NONE) {
      ogg->push_start_time =
          gst_ogg_stream_get_start_time_for_granulepos (&pad->map, granpos);
      GST_DEBUG_OBJECT (ogg, "Stream start time: %" GST_TIME_FORMAT,
          GST_TIME_ARGS (ogg->push_start_time));
    }
    ogg->push_time_offset =
        gst_ogg_stream_get_end_time_for_granulepos (&pad->map, granpos);
    if (ogg->push_time_offset > 0) {
      GST_DEBUG_OBJECT (ogg, "Bitrate since start: %" G_GUINT64_FORMAT,
          gst_util_uint64_scale (ogg->push_byte_offset, 8 * GST_SECOND,
              ogg->push_time_offset));
    }

    if (ogg->push_state == PUSH_DURATION) {
      GstClockTime t =
          gst_ogg_stream_get_end_time_for_granulepos (&pad->map, granpos);

      if (ogg->total_time == GST_CLOCK_TIME_NONE || t > ogg->total_time) {
        GST_DEBUG_OBJECT (ogg, "New total time: %" GST_TIME_FORMAT,
            GST_TIME_ARGS (t));
        ogg->total_time = t;
        ogg->push_time_length = t;
      }

      /* If we're still receiving data from before the seek segment, drop it */
      if (ogg->seek_event_drop_till != 0) {
        GST_PUSH_UNLOCK (ogg);
        return GST_FLOW_SKIP_PUSH;
      }

      /* If we were determining the duration of the stream, we're now done,
         and can get back to sending the original event we delayed.
         We stop a bit before the end of the stream, as if we get a EOS
         event and there is a queue2 upstream (such as when using playbin),
         it will pause the task *after* we come back from the EOS handler,
         so we cannot prevent the pausing by issuing a seek. */
      if (ogg->push_byte_offset >= ogg->push_byte_length) {
        GstMessage *message;
        GstFlowReturn res;

        /* tell the pipeline we've just found out the duration */
        ogg->push_time_length = ogg->total_time;
        GST_INFO_OBJECT (ogg, "New duration found: %" GST_TIME_FORMAT,
            GST_TIME_ARGS (ogg->total_time));
        message = gst_message_new_duration_changed (GST_OBJECT (ogg));
        gst_element_post_message (GST_ELEMENT (ogg), message);

        GST_DEBUG_OBJECT (ogg,
            "We're close enough to the end, and we're scared "
            "to get too close, seeking back to start");

        res = gst_ogg_demux_seek_back_after_push_duration_check_unlock (ogg);
        if (res != GST_FLOW_OK)
          return res;
        return GST_FLOW_SKIP_PUSH;
      } else {
        GST_PUSH_UNLOCK (ogg);
      }
      return GST_FLOW_SKIP_PUSH;
    }
  }

  /* if we're seeking, look at time, and decide what to do */
  if (ogg->push_state != PUSH_PLAYING && ogg->push_state != PUSH_LINEAR2) {
    GstClockTime t;
    gint64 best = -1;
    GstEvent *sevent;
    gboolean close_enough;
    float seek_quality;

    /* ignore -1 granpos when seeking, we want to sync on a real granpos */
    if (granpos < 0) {
      GST_PUSH_UNLOCK (ogg);
      if (ogg_stream_pagein (&pad->map.stream, page) != 0)
        goto choked;
      if (pad->current_granule == -1)
        gst_ogg_demux_setup_first_granule (ogg, pad, page);
      return GST_FLOW_SKIP_PUSH;
    }

    t = gst_ogg_stream_get_end_time_for_granulepos (&pad->map, granpos);

    if (ogg->push_state == PUSH_BISECT1 || ogg->push_state == PUSH_BISECT2) {
      GstClockTime sync_time;

      if (pad->push_sync_time == GST_CLOCK_TIME_NONE)
        pad->push_sync_time = t;
      GST_DEBUG_OBJECT (ogg, "Got PTS %" GST_TIME_FORMAT " for %s",
          GST_TIME_ARGS (t), gst_ogg_stream_get_media_type (&pad->map));
      sync_time = gst_ogg_demux_collect_sync_time (ogg, ogg->building_chain);
      if (sync_time == GST_CLOCK_TIME_NONE) {
        GST_PUSH_UNLOCK (ogg);
        GST_DEBUG_OBJECT (ogg,
            "Not enough timing info collected for sync, waiting for more");
        if (ogg_stream_pagein (&pad->map.stream, page) != 0)
          goto choked;
        if (pad->current_granule == -1)
          gst_ogg_demux_setup_first_granule (ogg, pad, page);
        return GST_FLOW_SKIP_PUSH;
      }
      ogg->push_last_seek_time = sync_time;

      GST_DEBUG_OBJECT (ogg,
          "Bisection just seeked at %" G_GINT64_FORMAT ", time %"
          GST_TIME_FORMAT ", target was %" GST_TIME_FORMAT,
          ogg->push_last_seek_offset,
          GST_TIME_ARGS (ogg->push_last_seek_time),
          GST_TIME_ARGS (ogg->push_seek_time_target));

      if (ogg->push_time1 != GST_CLOCK_TIME_NONE) {
        seek_quality = gst_ogg_demux_estimate_seek_quality (ogg);
        GST_DEBUG_OBJECT (ogg,
            "Interval was %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT " (%"
            G_GINT64_FORMAT "), time %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT
            " (%" GST_TIME_FORMAT "), seek quality %f", ogg->push_offset0,
            ogg->push_offset1, ogg->push_offset1 - ogg->push_offset0,
            GST_TIME_ARGS (ogg->push_time0), GST_TIME_ARGS (ogg->push_time1),
            GST_TIME_ARGS (ogg->push_time1 - ogg->push_time0), seek_quality);
      } else {
        /* in a open ended seek, we can't do bisection, so we pretend
           we like our result so far */
        seek_quality = 1.0f;
        GST_DEBUG_OBJECT (ogg,
            "Interval was %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT " (%"
            G_GINT64_FORMAT "), time %" GST_TIME_FORMAT " - unknown",
            ogg->push_offset0, ogg->push_offset1,
            ogg->push_offset1 - ogg->push_offset0,
            GST_TIME_ARGS (ogg->push_time0));
      }
      ogg->push_prev_seek_time = ogg->push_last_seek_time;

      gst_ogg_demux_setup_bisection_bounds (ogg);

      best = gst_ogg_demux_estimate_bisection_target (ogg, seek_quality);

      if (ogg->push_seek_time_target == 0) {
        GST_DEBUG_OBJECT (ogg, "Seeking to 0, deemed close enough");
        close_enough = (ogg->push_last_seek_time == 0);
      } else {
        /* TODO: make this dependent on framerate ? */
        GstClockTime time_threshold = GST_SECOND / 2;
        guint64 byte_threshold =
            (ogg->max_packet_size >
            64 * 1024 ? ogg->max_packet_size : 64 * 1024);

        /* We want to be within half a second before the target,
           or before the target and half less or equal to the max
           packet size left to search in */
        if (time_threshold > ogg->push_seek_time_target)
          time_threshold = ogg->push_seek_time_target;
        close_enough = ogg->push_last_seek_time < ogg->push_seek_time_target
            && (ogg->push_last_seek_time >=
            ogg->push_seek_time_target - time_threshold
            || ogg->push_offset1 <= ogg->push_offset0 + byte_threshold);
        GST_DEBUG_OBJECT (ogg,
            "testing if we're close enough: %" GST_TIME_FORMAT " <= %"
            GST_TIME_FORMAT " < %" GST_TIME_FORMAT ", or %" G_GUINT64_FORMAT
            " <= %" G_GUINT64_FORMAT " ? %s",
            GST_TIME_ARGS (ogg->push_seek_time_target - time_threshold),
            GST_TIME_ARGS (ogg->push_last_seek_time),
            GST_TIME_ARGS (ogg->push_seek_time_target),
            ogg->push_offset1 - ogg->push_offset0, byte_threshold,
            close_enough ? "Yes" : "No");
      }

      if (close_enough || best == ogg->push_last_seek_offset) {
        if (ogg->push_state == PUSH_BISECT1) {
          /* we now know the time segment we'll have to search for
             the second bisection */
          ogg->push_time0 = ogg->push_start_time;
          ogg->push_offset0 = 0;

          GST_DEBUG_OBJECT (ogg,
              "Seek to %" GST_TIME_FORMAT
              " (%lx) done, now gathering pages for all non-sparse streams",
              GST_TIME_ARGS (ogg->push_seek_time_target), (long) granpos);
          ogg->push_state = PUSH_LINEAR1;
        } else {
          /* If we're asked for an accurate seek, we'll go forward till
             we get to the original seek target time, else we'll just drop
             here at the keyframe */
          if (ogg->push_seek_flags & GST_SEEK_FLAG_ACCURATE) {
            GST_INFO_OBJECT (ogg,
                "Seek to keyframe at %" GST_TIME_FORMAT " done (we're at %"
                GST_TIME_FORMAT "), skipping to original target (%"
                GST_TIME_FORMAT ")",
                GST_TIME_ARGS (ogg->push_seek_time_target),
                GST_TIME_ARGS (sync_time),
                GST_TIME_ARGS (ogg->push_seek_time_original_target));
            ogg->push_state = PUSH_LINEAR2;
          } else {
            GST_INFO_OBJECT (ogg, "Seek to keyframe done, playing");

            /* we're synced to the seek target, so flush stream and stuff
               any queued pages into the stream so we start decoding there */
            ogg->push_state = PUSH_PLAYING;
          }
          gst_ogg_demux_update_bisection_stats (ogg);
        }
      }
    } else if (ogg->push_state == PUSH_LINEAR1) {
      if (pad->push_kf_time == GST_CLOCK_TIME_NONE) {
        GstClockTime earliest_keyframe_time;

        gst_ogg_demux_record_keyframe_time (ogg, pad, granpos);
        GST_DEBUG_OBJECT (ogg,
            "Previous keyframe for %s stream at %" GST_TIME_FORMAT,
            gst_ogg_stream_get_media_type (&pad->map),
            GST_TIME_ARGS (pad->push_kf_time));
        earliest_keyframe_time = gst_ogg_demux_get_earliest_keyframe_time (ogg);
        if (earliest_keyframe_time != GST_CLOCK_TIME_NONE) {
          if (earliest_keyframe_time > ogg->push_last_seek_time) {
            GST_INFO_OBJECT (ogg,
                "All non sparse streams now have a previous keyframe time, "
                "and we already decoded it, switching to playing");
            ogg->push_state = PUSH_PLAYING;
            gst_ogg_demux_update_bisection_stats (ogg);
          } else {
            GST_INFO_OBJECT (ogg,
                "All non sparse streams now have a previous keyframe time, "
                "bisecting again to %" GST_TIME_FORMAT,
                GST_TIME_ARGS (earliest_keyframe_time));

            ogg->push_seek_time_target = earliest_keyframe_time;
            ogg->push_offset0 = 0;
            ogg->push_time0 = ogg->push_start_time;
            ogg->push_offset1 = ogg->push_last_seek_offset;
            ogg->push_time1 = ogg->push_last_seek_time;
            ogg->push_prev_seek_time = GST_CLOCK_TIME_NONE;
            ogg->seek_secant = FALSE;
            ogg->seek_undershot = FALSE;

            ogg->push_state = PUSH_BISECT2;
            best = gst_ogg_demux_estimate_bisection_target (ogg, 1.0f);
          }
        }
      }
    }

    if (ogg->push_state == PUSH_BISECT1 || ogg->push_state == PUSH_BISECT2) {
      gint i;

      ogg_sync_reset (&ogg->sync);
      for (i = 0; i < ogg->building_chain->streams->len; i++) {
        GstOggPad *pad =
            g_array_index (ogg->building_chain->streams, GstOggPad *, i);

        pad->push_sync_time = GST_CLOCK_TIME_NONE;
        ogg_stream_reset (&pad->map.stream);
      }

      GST_DEBUG_OBJECT (ogg,
          "seeking to %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT, best,
          (gint64) - 1);
      /* do seek */
      g_assert (best != -1);
      ogg->push_bisection_steps[ogg->push_state == PUSH_BISECT2 ? 1 : 0]++;
      sevent =
          gst_event_new_seek (ogg->push_seek_rate, GST_FORMAT_BYTES,
          ogg->push_seek_flags, GST_SEEK_TYPE_SET, best,
          GST_SEEK_TYPE_NONE, -1);
      gst_event_set_seqnum (sevent, ogg->seqnum);

      gst_event_replace (&ogg->seek_event, sevent);
      gst_event_unref (sevent);
      GST_PUSH_UNLOCK (ogg);
      g_mutex_lock (&ogg->seek_event_mutex);
      g_cond_broadcast (&ogg->seek_event_cond);
      g_mutex_unlock (&ogg->seek_event_mutex);
      return GST_FLOW_SKIP_PUSH;
    }

    if (ogg->push_state != PUSH_PLAYING) {
      GST_PUSH_UNLOCK (ogg);
      return GST_FLOW_SKIP_PUSH;
    }
  }
  GST_PUSH_UNLOCK (ogg);

  return GST_FLOW_OK;

choked:
  {
    GST_WARNING_OBJECT (ogg,
        "ogg stream choked on page (serial %08x), "
        "resetting stream", pad->map.serialno);
    gst_ogg_pad_reset (pad);
    /* we continue to recover */
    return GST_FLOW_SKIP_PUSH;
  }
}

static void
gst_ogg_demux_query_duration_push (GstOggDemux * ogg)
{
  if (!ogg->pullmode && ogg->push_byte_length == -1) {
    GstQuery *query;
    gboolean seekable = FALSE;

    query = gst_query_new_seeking (GST_FORMAT_BYTES);
    if (gst_pad_peer_query (ogg->sinkpad, query))
      gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
    gst_query_unref (query);

    if (seekable) {
      gint64 length = -1;
      if (!gst_element_query_duration (GST_ELEMENT (ogg), GST_FORMAT_BYTES,
              &length)
          || length <= 0) {
        GST_DEBUG_OBJECT (ogg,
            "Unable to determine stream size, assuming live, seeking disabled");
        ogg->push_disable_seeking = TRUE;
      } else {
        ogg->push_disable_seeking = FALSE;
      }
    } else {
      GST_DEBUG_OBJECT (ogg, "Stream is not seekable, seeking disabled");
      ogg->push_disable_seeking = TRUE;
    }
  }
}

/* submit a page to an oggpad, this function will then submit all
 * the packets in the page.
 */
static GstFlowReturn
gst_ogg_pad_submit_page (GstOggPad * pad, ogg_page * page)
{
  GstFlowReturn result = GST_FLOW_OK;
  GstOggDemux *ogg;
  gboolean continued = FALSE;

  ogg = pad->ogg;

  /* for negative rates we read pages backwards and must therefore be careful
   * with continued pages */
  if (ogg->segment.rate < 0.0) {
    gint npackets;

    continued = ogg_page_continued (page);

    /* number of completed packets in the page */
    npackets = ogg_page_packets (page);
    if (!continued) {
      /* page is not continued so it contains at least one packet start. It's
       * possible that no packet ends on this page (npackets == 0). In that
       * case, the next (continued) page(s) we kept contain the remainder of the
       * packets. We mark npackets=1 to make us start decoding the pages in the
       * remainder of the algorithm. */
      if (npackets == 0)
        npackets = 1;
    }
    GST_LOG_OBJECT (ogg, "continued: %d, %d packets", continued, npackets);

    if (npackets == 0) {
      GST_LOG_OBJECT (ogg, "no decodable packets, we need a previous page");
      goto done;
    }
  }

  gst_ogg_demux_query_duration_push (ogg);

  /* keep track of time in push mode */
  if (!ogg->pullmode) {
    result = gst_ogg_pad_handle_push_mode_state (pad, page);
    if (result == GST_FLOW_SKIP_PUSH)
      return GST_FLOW_OK;
    if (result != GST_FLOW_OK)
      return result;
  }

  if (page->header_len + page->body_len > ogg->max_page_size)
    ogg->max_page_size = page->header_len + page->body_len;

  if (ogg_stream_pagein (&pad->map.stream, page) != 0)
    goto choked;
  if (pad->current_granule == -1)
    gst_ogg_demux_setup_first_granule (ogg, pad, page);

  /* flush all packets in the stream layer, this might not give a packet if
   * the page had no packets finishing on the page (npackets == 0). */
  result = gst_ogg_pad_stream_out (pad, 0);

  if (pad->continued) {
    ogg_packet packet;

    /* now send the continued pages to the stream layer */
    while (pad->continued) {
      ogg_page *p = (ogg_page *) pad->continued->data;

      GST_LOG_OBJECT (ogg, "submitting continued page %p", p);
      if (ogg_stream_pagein (&pad->map.stream, p) != 0)
        goto choked;

      pad->continued = g_list_delete_link (pad->continued, pad->continued);

      /* free the page */
      gst_ogg_page_free (p);
    }

    GST_LOG_OBJECT (ogg, "flushing last continued packet");
    /* flush 1 continued packet in the stream layer */
    result = gst_ogg_pad_stream_out (pad, 1);

    /* flush all remaining packets, we pushed them in the previous round.
     * We don't use _reset() because we still want to get the discont when
     * we submit a next page. */
    while (ogg_stream_packetout (&pad->map.stream, &packet) != 0);
  }

done:
  /* keep continued pages (only in reverse mode) */
  if (continued) {
    ogg_page *p = gst_ogg_page_copy (page);

    GST_LOG_OBJECT (ogg, "keeping continued page %p", p);
    pad->continued = g_list_prepend (pad->continued, p);
  }

  return result;

choked:
  {
    GST_WARNING_OBJECT (ogg,
        "ogg stream choked on page (serial %08x), "
        "resetting stream", pad->map.serialno);
    gst_ogg_pad_reset (pad);
    /* we continue to recover */
    return GST_FLOW_OK;
  }
}


static GstOggChain *
gst_ogg_chain_new (GstOggDemux * ogg)
{
  GstOggChain *chain = g_slice_new0 (GstOggChain);

  GST_DEBUG_OBJECT (ogg, "creating new chain %p", chain);
  chain->ogg = ogg;
  chain->offset = -1;
  chain->bytes = -1;
  chain->have_bos = FALSE;
  chain->streams = g_array_new (FALSE, TRUE, sizeof (GstOggPad *));
  chain->begin_time = GST_CLOCK_TIME_NONE;
  chain->segment_start = GST_CLOCK_TIME_NONE;
  chain->segment_stop = GST_CLOCK_TIME_NONE;
  chain->total_time = GST_CLOCK_TIME_NONE;

  return chain;
}

static void
gst_ogg_chain_free (GstOggChain * chain)
{
  gint i;

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

    gst_object_unref (pad);
  }
  g_array_free (chain->streams, TRUE);
  g_slice_free (GstOggChain, chain);
}

static void
gst_ogg_pad_mark_discont (GstOggPad * pad)
{
  GST_LOG_OBJECT (pad, "Marking discont on pad");
  pad->discont = TRUE;
  pad->map.last_size = 0;
}

static void
gst_ogg_chain_mark_discont (GstOggChain * chain)
{
  gint i;

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

    gst_ogg_pad_mark_discont (pad);
  }
}

static void
gst_ogg_chain_reset (GstOggChain * chain)
{
  gint i;

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

    gst_ogg_pad_reset (pad);
  }
}

static GstOggPad *
gst_ogg_chain_new_stream (GstOggChain * chain, guint32 serialno)
{
  GstOggPad *ret;
  gchar *name;

  GST_DEBUG_OBJECT (chain->ogg,
      "creating new stream %08x in chain %p", serialno, chain);

  name = g_strdup_printf ("src_%08x", serialno);
  ret = g_object_new (GST_TYPE_OGG_PAD, "name", name, NULL);
  g_free (name);
  /* we own this one */
  gst_object_ref_sink (ret);

  GST_PAD_DIRECTION (ret) = GST_PAD_SRC;
  gst_ogg_pad_mark_discont (ret);

  ret->chain = chain;
  ret->ogg = chain->ogg;

  ret->map.serialno = serialno;
  if (ogg_stream_init (&ret->map.stream, serialno) != 0)
    goto init_failed;

  GST_DEBUG_OBJECT (chain->ogg,
      "created new ogg src %p for stream with serial %08x", ret, serialno);

  g_array_append_val (chain->streams, ret);
  gst_pad_set_active (GST_PAD_CAST (ret), TRUE);

  return ret;

  /* ERRORS */
init_failed:
  {
    GST_ERROR ("Could not initialize ogg_stream struct for serial %08x",
        serialno);
    gst_object_unref (ret);
    return NULL;
  }
}

static GstOggPad *
gst_ogg_chain_get_stream (GstOggChain * chain, guint32 serialno)
{
  gint i;

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

    if (pad->map.serialno == serialno)
      return pad;
  }
  return NULL;
}

static gboolean
gst_ogg_chain_has_stream (GstOggChain * chain, guint32 serialno)
{
  return gst_ogg_chain_get_stream (chain, serialno) != NULL;
}

/* signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  ARG_0
      /* FILL ME */
};

static GstStaticPadTemplate ogg_demux_src_template_factory =
GST_STATIC_PAD_TEMPLATE ("src_%08x",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate ogg_demux_sink_template_factory =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/ogg; audio/ogg; video/ogg; application/kate")
    );

static void gst_ogg_demux_finalize (GObject * object);

static GstFlowReturn gst_ogg_demux_read_chain (GstOggDemux * ogg,
    GstOggChain ** chain);
static GstFlowReturn gst_ogg_demux_read_end_chain (GstOggDemux * ogg,
    GstOggChain * chain);

static gboolean gst_ogg_demux_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static void gst_ogg_demux_loop (GstOggPad * pad);
static GstFlowReturn gst_ogg_demux_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static gboolean gst_ogg_demux_sink_activate (GstPad * sinkpad,
    GstObject * parent);
static gboolean gst_ogg_demux_sink_activate_mode (GstPad * sinkpad,
    GstObject * parent, GstPadMode mode, gboolean active);
static GstStateChangeReturn gst_ogg_demux_change_state (GstElement * element,
    GstStateChange transition);

static void gst_ogg_print (GstOggDemux * demux);

#define gst_ogg_demux_parent_class parent_class
G_DEFINE_TYPE (GstOggDemux, gst_ogg_demux, GST_TYPE_ELEMENT);

static void
gst_ogg_demux_class_init (GstOggDemuxClass * klass)
{
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gst_element_class_set_static_metadata (gstelement_class,
      "Ogg demuxer", "Codec/Demuxer",
      "demux ogg streams (info about ogg: http://xiph.org)",
      "Wim Taymans <wim@fluendo.com>");

  gst_element_class_add_static_pad_template (gstelement_class,
      &ogg_demux_sink_template_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &ogg_demux_src_template_factory);

  gstelement_class->change_state = gst_ogg_demux_change_state;
  gstelement_class->send_event = gst_ogg_demux_receive_event;

  gobject_class->finalize = gst_ogg_demux_finalize;
}

static void
gst_ogg_demux_init (GstOggDemux * ogg)
{
  /* create the sink pad */
  ogg->sinkpad =
      gst_pad_new_from_static_template (&ogg_demux_sink_template_factory,
      "sink");

  gst_pad_set_event_function (ogg->sinkpad, gst_ogg_demux_sink_event);
  gst_pad_set_chain_function (ogg->sinkpad, gst_ogg_demux_chain);
  gst_pad_set_activate_function (ogg->sinkpad, gst_ogg_demux_sink_activate);
  gst_pad_set_activatemode_function (ogg->sinkpad,
      gst_ogg_demux_sink_activate_mode);
  gst_element_add_pad (GST_ELEMENT (ogg), ogg->sinkpad);

  g_mutex_init (&ogg->chain_lock);
  g_mutex_init (&ogg->push_lock);
  g_mutex_init (&ogg->seek_event_mutex);
  g_cond_init (&ogg->seek_event_cond);
  g_cond_init (&ogg->thread_started_cond);

  ogg->chains = g_array_new (FALSE, TRUE, sizeof (GstOggChain *));

  ogg->stats_nbisections = 0;
  ogg->stats_bisection_steps[0] = 0;
  ogg->stats_bisection_steps[1] = 0;
  ogg->stats_bisection_max_steps[0] = 0;
  ogg->stats_bisection_max_steps[1] = 0;

  ogg->newsegment = NULL;

  ogg->chunk_size = CHUNKSIZE;
  ogg->flowcombiner = gst_flow_combiner_new ();
}

static void
gst_ogg_demux_finalize (GObject * object)
{
  GstOggDemux *ogg;

  ogg = GST_OGG_DEMUX (object);

  g_array_free (ogg->chains, TRUE);
  g_mutex_clear (&ogg->chain_lock);
  g_mutex_clear (&ogg->push_lock);
  g_cond_clear (&ogg->seek_event_cond);
  g_cond_clear (&ogg->thread_started_cond);
  g_mutex_clear (&ogg->seek_event_mutex);

  ogg_sync_clear (&ogg->sync);

  if (ogg->newsegment)
    gst_event_unref (ogg->newsegment);

  gst_flow_combiner_free (ogg->flowcombiner);

  if (ogg->building_chain)
    gst_ogg_chain_free (ogg->building_chain);

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

static void
gst_ogg_demux_reset_streams (GstOggDemux * ogg)
{
  GstOggChain *chain;
  guint i;

  chain = ogg->current_chain;
  if (chain == NULL)
    return;

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *stream = g_array_index (chain->streams, GstOggPad *, i);

    stream->start_time = -1;
    stream->map.accumulated_granule = 0;
    stream->current_granule = -1;
    stream->keyframe_granule = -1;
  }
  ogg->building_chain = chain;
  GST_DEBUG_OBJECT (ogg, "Resetting current chain");
  ogg->current_chain = NULL;
  ogg->resync = TRUE;
  gst_ogg_chain_mark_discont (chain);

  ogg->chunk_size = CHUNKSIZE;
}

static gboolean
gst_ogg_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstOggDemux *ogg;

  ogg = GST_OGG_DEMUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      res = gst_ogg_demux_send_event (ogg, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      GST_DEBUG_OBJECT (ogg, "got a flush stop event");
      ogg_sync_reset (&ogg->sync);
      res = gst_ogg_demux_send_event (ogg, event);
      if (ogg->pullmode || ogg->push_state != PUSH_DURATION) {
        /* it's starting to feel reaaaally dirty :(
           if we're on a spliced seek to get duration, don't reset streams,
           we'll need them for the delayed seek */
        gst_ogg_demux_reset_streams (ogg);
      }
      break;
    case GST_EVENT_SEGMENT:
      GST_DEBUG_OBJECT (ogg, "got a new segment event");
      {
        GstSegment segment;
        gboolean update;

        gst_event_copy_segment (event, &segment);

        if (segment.format == GST_FORMAT_BYTES) {
          GST_PUSH_LOCK (ogg);
          ogg->push_byte_offset = segment.start;
          ogg->push_last_seek_offset = segment.start;

          if (gst_event_get_seqnum (event) == ogg->seqnum) {
            GstSeekType stop_type = GST_SEEK_TYPE_NONE;
            if (ogg->push_seek_time_original_stop != -1)
              stop_type = GST_SEEK_TYPE_SET;
            gst_segment_do_seek (&ogg->segment, ogg->push_seek_rate,
                GST_FORMAT_TIME, ogg->push_seek_flags, GST_SEEK_TYPE_SET,
                ogg->push_seek_time_original_target, stop_type,
                ogg->push_seek_time_original_stop, &update);
          }

          if (!ogg->pullmode && !(ogg->push_seek_flags & GST_SEEK_FLAG_FLUSH)) {
            int i;
            GstOggChain *chain = ogg->current_chain;

            ogg->push_seek_flags = 0;
            if (!chain) {
              /* This will happen when we bisect, as we clear the chain when
                 we do the first seek. On subsequent ones, we just reset the
                 ogg sync object as we already reset the chain */
              GST_DEBUG_OBJECT (ogg, "No chain, just resetting ogg sync");
              ogg_sync_reset (&ogg->sync);
            } else {
              /* reset pad push mode seeking state */
              for (i = 0; i < chain->streams->len; i++) {
                GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
                pad->push_kf_time = GST_CLOCK_TIME_NONE;
                pad->push_sync_time = GST_CLOCK_TIME_NONE;
              }
              ogg_sync_reset (&ogg->sync);
              gst_ogg_demux_reset_streams (ogg);
            }
          }

          if (!ogg->pullmode) {
            if (ogg->seek_event_drop_till == gst_event_get_seqnum (event)) {
              GST_DEBUG_OBJECT (ogg, "Got event seqnum %u, stopping dropping",
                  ogg->seek_event_drop_till);
              ogg->seek_event_drop_till = 0;
            }
          }
          GST_PUSH_UNLOCK (ogg);
        } else {
          GST_WARNING_OBJECT (ogg, "unexpected segment format: %s",
              gst_format_get_name (segment.format));
        }
      }

      gst_event_unref (event);
      res = TRUE;
      break;
    case GST_EVENT_EOS:
    {
      GST_DEBUG_OBJECT (ogg, "got an EOS event");
      GST_PUSH_LOCK (ogg);
      if (ogg->push_state == PUSH_DURATION) {
        GST_DEBUG_OBJECT (ogg, "Got EOS while determining length");
        res = gst_ogg_demux_seek_back_after_push_duration_check_unlock (ogg);
        if (res != GST_FLOW_OK) {
          GST_DEBUG_OBJECT (ogg, "Error seeking back after duration check: %d",
              res);
        }
        break;
      } else
        GST_PUSH_UNLOCK (ogg);
      res = gst_ogg_demux_send_event (ogg, event);
      if (ogg->current_chain == NULL) {
        GST_WARNING_OBJECT (ogg,
            "EOS while trying to retrieve chain, seeking disabled");
        ogg->push_disable_seeking = TRUE;
        res = TRUE;
      }
      break;
    }
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

  return res;
}

/* submit the given buffer to the ogg sync */
static GstFlowReturn
gst_ogg_demux_submit_buffer (GstOggDemux * ogg, GstBuffer * buffer)
{
  gsize size;
  gchar *oggbuffer;
  GstFlowReturn ret = GST_FLOW_OK;

  size = gst_buffer_get_size (buffer);
  GST_DEBUG_OBJECT (ogg, "submitting %" G_GSIZE_FORMAT " bytes", size);
  if (G_UNLIKELY (size == 0))
    goto done;

  oggbuffer = ogg_sync_buffer (&ogg->sync, size);
  if (G_UNLIKELY (oggbuffer == NULL))
    goto no_buffer;

  gst_buffer_extract (buffer, 0, oggbuffer, size);

  if (G_UNLIKELY (ogg_sync_wrote (&ogg->sync, size) < 0))
    goto write_failed;

  if (!ogg->pullmode) {
    GST_PUSH_LOCK (ogg);
    ogg->push_byte_offset += size;
    GST_PUSH_UNLOCK (ogg);
  }

done:
  gst_buffer_unref (buffer);

  return ret;

  /* ERRORS */
no_buffer:
  {
    GST_ELEMENT_ERROR (ogg, STREAM, DECODE,
        (NULL), ("failed to get ogg sync buffer"));
    ret = GST_FLOW_ERROR;
    goto done;
  }
write_failed:
  {
    GST_ELEMENT_ERROR (ogg, STREAM, DECODE, (NULL),
        ("failed to write %" G_GSIZE_FORMAT " bytes to the sync buffer", size));
    ret = GST_FLOW_ERROR;
    goto done;
  }
}

/* in random access mode this code updates the current read position
 * and resets the ogg sync buffer so that the next read will happen
 * from this new location.
 */
static void
gst_ogg_demux_seek (GstOggDemux * ogg, gint64 offset)
{
  GST_LOG_OBJECT (ogg, "seeking to %" G_GINT64_FORMAT, offset);

  ogg->offset = offset;
  ogg->read_offset = offset;
  ogg_sync_reset (&ogg->sync);
}

/* read more data from the current offset and submit to
 * the ogg sync layer.
 */
static GstFlowReturn
gst_ogg_demux_get_data (GstOggDemux * ogg, gint64 end_offset)
{
  GstFlowReturn ret;
  GstBuffer *buffer;
  gchar *oggbuffer;
  gsize size;

  GST_LOG_OBJECT (ogg,
      "get data %" G_GINT64_FORMAT " %" G_GINT64_FORMAT " %" G_GINT64_FORMAT,
      ogg->read_offset, ogg->length, end_offset);

  if (end_offset > 0 && ogg->read_offset >= end_offset)
    goto boundary_reached;

  if (ogg->read_offset == ogg->length)
    goto eos;

  oggbuffer = ogg_sync_buffer (&ogg->sync, ogg->chunk_size);
  if (G_UNLIKELY (oggbuffer == NULL))
    goto no_buffer;

  buffer =
      gst_buffer_new_wrapped_full (0, oggbuffer, ogg->chunk_size, 0,
      ogg->chunk_size, NULL, NULL);

  ret =
      gst_pad_pull_range (ogg->sinkpad, ogg->read_offset, ogg->chunk_size,
      &buffer);
  if (ret != GST_FLOW_OK)
    goto error;

  size = gst_buffer_get_size (buffer);

  if (G_UNLIKELY (ogg_sync_wrote (&ogg->sync, size) < 0))
    goto write_failed;

  ogg->read_offset += size;
  gst_buffer_unref (buffer);

  return ret;

  /* ERROR */
boundary_reached:
  {
    GST_LOG_OBJECT (ogg, "reached boundary");
    return GST_FLOW_LIMIT;
  }
eos:
  {
    GST_LOG_OBJECT (ogg, "reached EOS");
    return GST_FLOW_EOS;
  }
no_buffer:
  {
    GST_ELEMENT_ERROR (ogg, STREAM, DECODE,
        (NULL), ("failed to get ogg sync buffer"));
    return GST_FLOW_ERROR;
  }
error:
  {
    GST_WARNING_OBJECT (ogg, "got %d (%s) from pull range", ret,
        gst_flow_get_name (ret));
    gst_buffer_unref (buffer);
    return ret;
  }
write_failed:
  {
    GST_ELEMENT_ERROR (ogg, STREAM, DECODE, (NULL),
        ("failed to write %" G_GSIZE_FORMAT " bytes to the sync buffer", size));
    gst_buffer_unref (buffer);
    return GST_FLOW_ERROR;
  }
}

/* Read the next page from the current offset.
 * boundary: number of bytes ahead we allow looking for;
 * -1 if no boundary
 *
 * @offset will contain the offset the next page starts at when this function
 * returns GST_FLOW_OK.
 *
 * GST_FLOW_EOS is returned on EOS.
 *
 * GST_FLOW_LIMIT is returned when we did not find a page before the
 * boundary. If @boundary is -1, this is never returned.
 *
 * Any other error returned while retrieving data from the peer is returned as
 * is.
 */
static GstFlowReturn
gst_ogg_demux_get_next_page (GstOggDemux * ogg, ogg_page * og,
    gint64 boundary, gint64 * offset)
{
  gint64 end_offset = -1;
  GstFlowReturn ret;

  GST_LOG_OBJECT (ogg,
      "get next page, current offset %" G_GINT64_FORMAT ", bytes boundary %"
      G_GINT64_FORMAT, ogg->offset, boundary);

  if (boundary >= 0)
    end_offset = ogg->offset + boundary;

  while (TRUE) {
    glong more;

    if (end_offset > 0 && ogg->offset >= end_offset)
      goto boundary_reached;

    more = ogg_sync_pageseek (&ogg->sync, og);

    GST_LOG_OBJECT (ogg, "pageseek gave %ld", more);

    if (more < 0) {
      /* skipped n bytes */
      ogg->offset -= more;
      GST_LOG_OBJECT (ogg, "skipped %ld bytes, offset %" G_GINT64_FORMAT,
          more, ogg->offset);
    } else if (more == 0) {
      /* we need more data */
      if (boundary == 0)
        goto boundary_reached;

      GST_LOG_OBJECT (ogg, "need more data");
      ret = gst_ogg_demux_get_data (ogg, end_offset);
      if (ret != GST_FLOW_OK)
        break;
    } else {
      gint64 res_offset = ogg->offset;

      /* got a page.  Return the offset at the page beginning,
         advance the internal offset past the page end */
      if (offset)
        *offset = res_offset;
      ret = GST_FLOW_OK;

      ogg->offset += more;

      GST_LOG_OBJECT (ogg,
          "got page at %" G_GINT64_FORMAT ", serial %08x, end at %"
          G_GINT64_FORMAT ", granule %" G_GINT64_FORMAT, res_offset,
          ogg_page_serialno (og), ogg->offset,
          (gint64) ogg_page_granulepos (og));
      break;
    }
  }
  GST_LOG_OBJECT (ogg, "returning %d", ret);

  return ret;

  /* ERRORS */
boundary_reached:
  {
    GST_LOG_OBJECT (ogg,
        "offset %" G_GINT64_FORMAT " >= end_offset %" G_GINT64_FORMAT,
        ogg->offset, end_offset);
    return GST_FLOW_LIMIT;
  }
}

/* from the current offset, find the previous page, seeking backwards
 * until we find the page. 
 */
static GstFlowReturn
gst_ogg_demux_get_prev_page (GstOggDemux * ogg, ogg_page * og, gint64 * offset)
{
  GstFlowReturn ret;
  gint64 begin = ogg->offset;
  gint64 end = begin;
  gint64 cur_offset = -1;

  GST_LOG_OBJECT (ogg, "getting page before %" G_GINT64_FORMAT, begin);

  while (cur_offset == -1) {
    begin -= ogg->chunk_size;
    if (begin < 0)
      begin = 0;

    /* seek ogg->chunk_size back */
    GST_LOG_OBJECT (ogg, "seeking back to %" G_GINT64_FORMAT, begin);
    gst_ogg_demux_seek (ogg, begin);

    /* now continue reading until we run out of data, if we find a page
     * start, we save it. It might not be the final page as there could be
     * another page after this one. */
    while (ogg->offset < end) {
      gint64 new_offset, boundary;

      /* An Ogg page cannot be more than a bit less than 64 KB, so we can
         bound the boundary to that size when searching backwards if we
         haven't found a page yet. So the most we have to look at is twice
         the max page size, which is the worst case if we start scanning
         just after a large page, after which also lies a large page. */
      boundary = end - ogg->offset;
      if (boundary > 2 * MAX_OGG_PAGE_SIZE)
        boundary = 2 * MAX_OGG_PAGE_SIZE;

      ret = gst_ogg_demux_get_next_page (ogg, og, boundary, &new_offset);
      /* we hit the upper limit, offset contains the last page start */
      if (ret == GST_FLOW_LIMIT) {
        GST_LOG_OBJECT (ogg, "hit limit");
        break;
      }
      /* something went wrong */
      if (ret == GST_FLOW_EOS) {
        new_offset = 0;
        GST_LOG_OBJECT (ogg, "got unexpected");
        /* We hit EOS. */
        goto beach;
      } else if (ret != GST_FLOW_OK) {
        GST_LOG_OBJECT (ogg, "got error %d", ret);
        return ret;
      }

      GST_LOG_OBJECT (ogg, "found page at %" G_GINT64_FORMAT, new_offset);

      /* offset is next page start */
      cur_offset = new_offset;
    }
  }

  GST_LOG_OBJECT (ogg, "found previous page at %" G_GINT64_FORMAT, cur_offset);

  /* we have the offset.  Actually snork and hold the page now */
  gst_ogg_demux_seek (ogg, cur_offset);
  ret = gst_ogg_demux_get_next_page (ogg, og, -1, NULL);
  if (ret != GST_FLOW_OK) {
    GST_WARNING_OBJECT (ogg, "can't get last page at %" G_GINT64_FORMAT,
        cur_offset);
    /* this shouldn't be possible */
    return ret;
  }

  if (offset)
    *offset = cur_offset;

beach:
  return ret;
}

static gboolean
gst_ogg_demux_deactivate_current_chain (GstOggDemux * ogg)
{
  gint i;
  GstOggChain *chain = ogg->current_chain;

  if (chain == NULL)
    return TRUE;

  GST_DEBUG_OBJECT (ogg, "deactivating chain %p", chain);

  /* send EOS on all the pads */
  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
    GstEvent *event;

    if (!pad->added)
      continue;

    event = gst_event_new_eos ();
    gst_event_set_seqnum (event, ogg->seqnum);
    gst_pad_push_event (GST_PAD_CAST (pad), event);

    GST_DEBUG_OBJECT (ogg, "removing pad %" GST_PTR_FORMAT, pad);

    /* deactivate first */
    gst_pad_set_active (GST_PAD_CAST (pad), FALSE);

    gst_flow_combiner_remove_pad (ogg->flowcombiner, GST_PAD_CAST (pad));

    gst_element_remove_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad));

    pad->added = FALSE;
  }

  /* if we cannot seek back to the chain, we can destroy the chain 
   * completely */
  if (!ogg->pullmode) {
    if (ogg->building_chain == chain)
      ogg->building_chain = NULL;
    ogg->current_chain = NULL;
    gst_ogg_chain_free (chain);
  }

  return TRUE;
}

static GstCaps *
gst_ogg_demux_set_header_on_caps (GstOggDemux * ogg, GstCaps * caps,
    GList * headers)
{
  GstStructure *structure;
  GValue array = { 0 };

  GST_LOG_OBJECT (ogg, "caps: %" GST_PTR_FORMAT, caps);

  if (G_UNLIKELY (!caps))
    return NULL;
  if (G_UNLIKELY (!headers))
    return caps;

  caps = gst_caps_make_writable (caps);
  structure = gst_caps_get_structure (caps, 0);

  g_value_init (&array, GST_TYPE_ARRAY);

  while (headers) {
    GValue value = { 0 };
    GstBuffer *buffer;
    ogg_packet *op = headers->data;
    g_assert (op);
    buffer = gst_buffer_new_and_alloc (op->bytes);
    if (op->bytes)
      gst_buffer_fill (buffer, 0, op->packet, op->bytes);
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
    g_value_init (&value, GST_TYPE_BUFFER);
    gst_value_take_buffer (&value, buffer);
    gst_value_array_append_value (&array, &value);
    g_value_unset (&value);
    headers = headers->next;
  }

  gst_structure_take_value (structure, "streamheader", &array);
  GST_LOG_OBJECT (ogg, "here are the newly set caps: %" GST_PTR_FORMAT, caps);

  return caps;
}

static void
gst_ogg_demux_push_queued_buffers (GstOggDemux * ogg, GstOggPad * pad)
{
  GList *walk;

  /* push queued packets */
  for (walk = pad->map.queued; walk; walk = g_list_next (walk)) {
    ogg_packet *p = walk->data;

    gst_ogg_demux_chain_peer (pad, p, TRUE);
    _ogg_packet_free (p);
  }
  /* and free the queued buffers */
  g_list_free (pad->map.queued);
  pad->map.queued = NULL;
}

static gboolean
gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
    GstEvent * event)
{
  gint i;
  gint bitrate, idx_bitrate;

  g_return_val_if_fail (chain != NULL, FALSE);

  if (chain == ogg->current_chain) {
    if (event)
      gst_event_unref (event);

    for (i = 0; i < chain->streams->len; i++) {
      GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
      gst_ogg_demux_push_queued_buffers (ogg, pad);
    }
    return TRUE;
  }


  GST_DEBUG_OBJECT (ogg, "activating chain %p", chain);

  bitrate = idx_bitrate = 0;

  /* first add the pads */
  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad;
    GstEvent *ss_event;
    gchar *stream_id;

    pad = g_array_index (chain->streams, GstOggPad *, i);

    if (pad->map.idx_bitrate)
      idx_bitrate = MAX (idx_bitrate, pad->map.idx_bitrate);

    bitrate += pad->map.bitrate;

    /* mark discont */
    gst_ogg_pad_mark_discont (pad);
    pad->last_ret = GST_FLOW_OK;

    if (pad->map.is_skeleton || pad->map.is_cmml || pad->added
        || !pad->map.caps)
      continue;

    GST_DEBUG_OBJECT (ogg, "adding pad %" GST_PTR_FORMAT, pad);

    /* activate first */
    gst_pad_set_active (GST_PAD_CAST (pad), TRUE);

    stream_id =
        gst_pad_create_stream_id_printf (GST_PAD (pad), GST_ELEMENT_CAST (ogg),
        "%08x", pad->map.serialno);
    ss_event =
        gst_pad_get_sticky_event (ogg->sinkpad, GST_EVENT_STREAM_START, 0);
    if (ss_event) {
      if (gst_event_parse_group_id (ss_event, &ogg->group_id))
        ogg->have_group_id = TRUE;
      else
        ogg->have_group_id = FALSE;
      gst_event_unref (ss_event);
    } else if (!ogg->have_group_id) {
      ogg->have_group_id = TRUE;
      ogg->group_id = gst_util_group_id_next ();
    }
    ss_event = gst_event_new_stream_start (stream_id);
    if (ogg->have_group_id)
      gst_event_set_group_id (ss_event, ogg->group_id);

    gst_pad_push_event (GST_PAD (pad), ss_event);
    g_free (stream_id);

    /* Set headers on caps */
    pad->map.caps =
        gst_ogg_demux_set_header_on_caps (ogg, pad->map.caps, pad->map.headers);
    gst_pad_set_caps (GST_PAD_CAST (pad), pad->map.caps);

    gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad));
    pad->added = TRUE;
    gst_flow_combiner_add_pad (ogg->flowcombiner, GST_PAD_CAST (pad));
  }
  /* prefer the index bitrate over the ones encoded in the streams */
  ogg->bitrate = (idx_bitrate ? idx_bitrate : bitrate);

  /* after adding the new pads, remove the old pads */
  gst_ogg_demux_deactivate_current_chain (ogg);

  GST_DEBUG_OBJECT (ogg, "Setting current chain to %p", chain);
  ogg->current_chain = chain;

  /* we are finished now */
  gst_element_no_more_pads (GST_ELEMENT (ogg));

  GST_DEBUG_OBJECT (ogg, "starting chain");

  /* then send out any headers and queued packets */
  for (i = 0; i < chain->streams->len; i++) {
    GList *walk;
    GstOggPad *pad;
    GstTagList *tags;

    pad = g_array_index (chain->streams, GstOggPad *, i);

    /* Skip pads that were not added, e.g. Skeleton streams */
    if (!pad->added)
      continue;

    /* FIXME, must be sent from the streaming thread */
    if (event)
      gst_pad_push_event (GST_PAD_CAST (pad), gst_event_ref (event));

    /* FIXME also streaming thread */
    if (pad->map.taglist) {
      GST_DEBUG_OBJECT (ogg, "pushing tags");
      gst_pad_push_event (GST_PAD_CAST (pad),
          gst_event_new_tag (pad->map.taglist));
      pad->map.taglist = NULL;
    }

    tags = gst_tag_list_new (GST_TAG_CONTAINER_FORMAT, "Ogg", NULL);
    gst_tag_list_set_scope (tags, GST_TAG_SCOPE_GLOBAL);
    gst_pad_push_event (GST_PAD (pad), gst_event_new_tag (tags));

    GST_DEBUG_OBJECT (ogg, "pushing headers");
    /* push headers */
    for (walk = pad->map.headers; walk; walk = g_list_next (walk)) {
      ogg_packet *p = walk->data;

      gst_ogg_demux_chain_peer (pad, p, TRUE);
    }

    GST_DEBUG_OBJECT (ogg, "pushing queued buffers");
    gst_ogg_demux_push_queued_buffers (ogg, pad);
  }

  if (event)
    gst_event_unref (event);

  return TRUE;
}

static gboolean
do_binary_search (GstOggDemux * ogg, GstOggChain * chain, gint64 begin,
    gint64 end, gint64 begintime, gint64 endtime, gint64 target,
    gint64 * offset, gboolean only_serial_no, gint serialno)
{
  gint64 best;
  GstFlowReturn ret;
  gint64 result = 0;

  best = begin;

  GST_DEBUG_OBJECT (ogg,
      "chain offset %" G_GINT64_FORMAT ", end offset %" G_GINT64_FORMAT,
      begin, end);
  GST_DEBUG_OBJECT (ogg,
      "chain begin time %" GST_TIME_FORMAT ", end time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (begintime), GST_TIME_ARGS (endtime));
  GST_DEBUG_OBJECT (ogg, "target %" GST_TIME_FORMAT, GST_TIME_ARGS (target));

  /* perform the seek */
  while (begin < end) {
    gint64 bisect;

    if ((end - begin < ogg->chunk_size) || (endtime == begintime)) {
      bisect = begin;
    } else {
      /* take a (pretty decent) guess, avoiding overflow */
      gint64 rate = (end - begin) * GST_MSECOND / (endtime - begintime);

      bisect =
          (target - begintime) / GST_MSECOND * rate + begin - ogg->chunk_size;

      if (bisect <= begin)
        bisect = begin;
      GST_DEBUG_OBJECT (ogg, "Initial guess: %" G_GINT64_FORMAT, bisect);
    }
    gst_ogg_demux_seek (ogg, bisect);

    while (begin < end) {
      ogg_page og;

      GST_DEBUG_OBJECT (ogg,
          "after seek, bisect %" G_GINT64_FORMAT ", begin %" G_GINT64_FORMAT
          ", end %" G_GINT64_FORMAT, bisect, begin, end);

      ret = gst_ogg_demux_get_next_page (ogg, &og, end - ogg->offset, &result);
      GST_LOG_OBJECT (ogg, "looking for next page returned %" G_GINT64_FORMAT,
          result);

      if (ret == GST_FLOW_LIMIT) {
        /* we hit the upper limit, go back a bit */
        if (bisect <= begin + 1) {
          end = begin;          /* found it */
        } else {
          if (bisect == 0)
            goto seek_error;

          bisect -= ogg->chunk_size;
          if (bisect <= begin)
            bisect = begin + 1;

          gst_ogg_demux_seek (ogg, bisect);
        }
      } else if (ret == GST_FLOW_OK) {
        /* found offset of next ogg page */
        gint64 granulepos;
        GstClockTime granuletime;
        GstOggPad *pad;

        /* get the granulepos */
        GST_LOG_OBJECT (ogg, "found next ogg page at %" G_GINT64_FORMAT,
            result);
        granulepos = ogg_page_granulepos (&og);
        if (granulepos == -1) {
          GST_LOG_OBJECT (ogg, "granulepos of next page is -1");
          continue;
        }

        /* Avoid seeking to an incorrect granuletime by only considering 
           the stream for which we found the earliest time */
        if (only_serial_no && ogg_page_serialno (&og) != serialno)
          continue;

        /* get the stream */
        pad = gst_ogg_chain_get_stream (chain, ogg_page_serialno (&og));
        if (pad == NULL || pad->map.is_skeleton)
          continue;

        /* convert granulepos to time */
        granuletime = gst_ogg_stream_get_end_time_for_granulepos (&pad->map,
            granulepos);
        if (granuletime < pad->start_time)
          continue;

        GST_LOG_OBJECT (ogg, "granulepos %" G_GINT64_FORMAT " maps to PTS %"
            GST_TIME_FORMAT, granulepos, GST_TIME_ARGS (granuletime));

        granuletime -= pad->start_time;
        granuletime += chain->begin_time;

        GST_DEBUG_OBJECT (ogg,
            "found page with granule %" G_GINT64_FORMAT " and time %"
            GST_TIME_FORMAT, granulepos, GST_TIME_ARGS (granuletime));

        if (granuletime < target) {
          best = result;        /* raw offset of packet with granulepos */
          begin = ogg->offset;  /* raw offset of next page */
          begintime = granuletime;

          bisect = begin;       /* *not* begin + 1 */
        } else {
          if (bisect <= begin + 1) {
            end = begin;        /* found it */
          } else {
            if (end == ogg->offset) {   /* we're pretty close - we'd be stuck in */
              end = result;
              bisect -= ogg->chunk_size;        /* an endless loop otherwise. */
              if (bisect <= begin)
                bisect = begin + 1;
              gst_ogg_demux_seek (ogg, bisect);
            } else {
              end = result;
              endtime = granuletime;
              break;
            }
          }
        }
      } else
        goto seek_error;
    }
  }
  GST_DEBUG_OBJECT (ogg, "seeking to %" G_GINT64_FORMAT, best);
  gst_ogg_demux_seek (ogg, best);
  *offset = best;

  return TRUE;

  /* ERRORS */
seek_error:
  {
    GST_DEBUG_OBJECT (ogg, "got a seek error");
    return FALSE;
  }
}

static gboolean
do_index_search (GstOggDemux * ogg, GstOggChain * chain, gint64 begin,
    gint64 end, gint64 begintime, gint64 endtime, gint64 target,
    gint64 * p_offset, gint64 * p_timestamp)
{
  guint i;
  guint64 timestamp, offset;
  guint64 r_timestamp, r_offset;
  gboolean result = FALSE;

  target -= begintime;

  r_offset = -1;
  r_timestamp = -1;

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

    timestamp = target;
    if (gst_ogg_map_search_index (&pad->map, TRUE, &timestamp, &offset)) {
      GST_INFO ("found %" G_GUINT64_FORMAT " at offset %" G_GUINT64_FORMAT,
          timestamp, offset);

      if (r_offset == -1 || offset < r_offset) {
        r_offset = offset;
        r_timestamp = timestamp;
      }
      result |= TRUE;
    }
  }

  if (p_timestamp)
    *p_timestamp = r_timestamp;
  if (p_offset)
    *p_offset = r_offset;

  return result;
}

/*
 * do seek to time @position, return FALSE or chain and TRUE
 */
static gboolean
gst_ogg_demux_do_seek (GstOggDemux * ogg, GstSegment * segment,
    gboolean accurate, gboolean keyframe, GstOggChain ** rchain)
{
  guint64 position;
  GstOggChain *chain = NULL;
  gint64 begin, end;
  gint64 begintime, endtime;
  gint64 target, keytarget;
  gint64 best;
  gint64 total;
  gint64 result = 0;
  GstFlowReturn ret;
  gint i, pending;
  gint serialno = 0;
  gboolean found_keyframe = FALSE;
  GstClockTime ts, first_ts = GST_CLOCK_TIME_NONE;

  position = segment->position;

  /* first find the chain to search in */
  total = ogg->total_time;
  if (ogg->chains->len == 0)
    goto no_chains;

  for (i = ogg->chains->len - 1; i >= 0; i--) {
    chain = g_array_index (ogg->chains, GstOggChain *, i);
    total -= chain->total_time;
    if (position >= total)
      break;
  }

  /* first step, locate page containing the required data */
  begin = chain->offset;
  end = chain->end_offset;
  begintime = chain->begin_time;
  endtime = begintime + chain->total_time;
  target = position - total + begintime;

  if (!do_binary_search (ogg, chain, begin, end, begintime, endtime, target,
          &best, FALSE, 0))
    goto seek_error;

  /* second step: find pages for all relevant streams. We use the
   * keyframe_granule to keep track of which ones we saw. If we have
   * seen a page for each stream we can calculate the positions of
   * each keyframe.
   * Relevant streams are defined as those streams which are not
   * Skeleton (which only has header pages). Discontinuous streams
   * such as Kate and CMML are currently excluded, as they could
   * cause performance issues if there are few pages in the area.
   * TODO: We might want to include them on a flag, if we want to
   * not miss a subtitle (Kate has repeat packets for this purpose,
   * but a stream does not have to use them). */
  pending = chain->streams->len;
  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
    if (!pad) {
      GST_WARNING_OBJECT (ogg, "No pad at index %d", i);
      pending--;
      continue;
    }
    if (pad->map.is_skeleton) {
      GST_DEBUG_OBJECT (ogg, "Not finding pages for Skeleton stream %08x",
          pad->map.serialno);
      pending--;
      continue;
    }
    if (pad->map.is_sparse) {
      GST_DEBUG_OBJECT (ogg, "Not finding pages for sparse stream %08x (%s)",
          pad->map.serialno, gst_ogg_stream_get_media_type (&pad->map));
      pending--;
      continue;
    }
  }
  GST_DEBUG_OBJECT (ogg, "find keyframes for %d/%d streams", pending,
      chain->streams->len);

  /* figure out where the keyframes are */
  keytarget = target;

  while (TRUE) {
    ogg_page og;
    gint64 granulepos;
    GstOggPad *pad;
    GstClockTime keyframe_time, granule_time;

    ret = gst_ogg_demux_get_next_page (ogg, &og, end - ogg->offset, &result);
    GST_LOG_OBJECT (ogg, "looking for next page returned %" G_GINT64_FORMAT,
        result);
    if (ret == GST_FLOW_LIMIT) {
      GST_LOG_OBJECT (ogg, "reached limit");
      break;
    } else if (ret != GST_FLOW_OK)
      goto seek_error;

    /* get the stream */
    pad = gst_ogg_chain_get_stream (chain, ogg_page_serialno (&og));
    if (pad == NULL)
      continue;

    if (pad->map.is_skeleton || pad->map.is_sparse)
      goto next;

    granulepos = ogg_page_granulepos (&og);
    if (granulepos == -1 || granulepos == 0) {
      GST_LOG_OBJECT (ogg, "granulepos of next page is -1");
      continue;
    }

    /* We have a valid granpos, and we bail out when the time since the
       first seen time to the time corresponding to this granpos is larger
       then a threshold, to guard against some streams having large holes
       (eg, a stream ending early, which would cause seeking after that
       to fill up a queue for streams still active). */
    ts = gst_ogg_stream_get_end_time_for_granulepos (&pad->map, granulepos);
    if (GST_CLOCK_TIME_IS_VALID (ts)) {
      if (first_ts == GST_CLOCK_TIME_NONE) {
        GST_WARNING_OBJECT (pad, "Locking on pts %" GST_TIME_FORMAT,
            GST_TIME_ARGS (ts));
        first_ts = ts;
      }
      if (ts - first_ts > SEEK_GIVE_UP_THRESHOLD) {
        GST_WARNING_OBJECT (pad,
            "No data found for %" GST_TIME_FORMAT ", giving up",
            GST_TIME_ARGS (SEEK_GIVE_UP_THRESHOLD));
        found_keyframe = FALSE;
        keytarget = target;
        break;
      }
    }

    /* in reverse we want to go past the page with the lower timestamp */
    if (segment->rate < 0.0) {
      /* get time for this pad */
      granule_time = gst_ogg_stream_get_end_time_for_granulepos (&pad->map,
          granulepos);

      /* Convert to stream time */
      granule_time -= pad->start_time;
      granule_time += chain->begin_time;

      GST_LOG_OBJECT (ogg,
          "looking at page with time %" GST_TIME_FORMAT ", target %"
          GST_TIME_FORMAT, GST_TIME_ARGS (granule_time),
          GST_TIME_ARGS (target));
      if (granule_time < target)
        continue;
    }

    /* we've seen this pad before */
    if (pad->keyframe_granule != -1)
      continue;

    /* convert granule of this pad to the granule of the keyframe */
    pad->keyframe_granule =
        gst_ogg_stream_granulepos_to_key_granule (&pad->map, granulepos);
    GST_LOG_OBJECT (ogg, "marking stream granule %" G_GINT64_FORMAT,
        pad->keyframe_granule);

    /* get time of the keyframe */
    keyframe_time =
        gst_ogg_stream_granule_to_time (&pad->map, pad->keyframe_granule);
    GST_LOG_OBJECT (ogg,
        "stream %08x keyframe granule PTS %" GST_TIME_FORMAT
        " target %" GST_TIME_FORMAT,
        pad->map.serialno, GST_TIME_ARGS (keyframe_time),
        GST_TIME_ARGS (keytarget));

    /* collect smallest value */
    if (keyframe_time != -1) {
      keyframe_time -= pad->start_time;
      keyframe_time += begintime;
      if (keyframe_time < keytarget) {
        serialno = pad->map.serialno;
        keytarget = keyframe_time;
        found_keyframe = TRUE;
        GST_LOG_OBJECT (ogg, "storing keytarget %" GST_TIME_FORMAT,
            GST_TIME_ARGS (keytarget));
      }
    }

  next:
    pending--;
    if (pending == 0)
      break;
  }

  /* for negative rates we will get to the keyframe backwards */
  if (segment->rate < 0.0)
    goto done;

  /* No keyframe found, no need to bisect again, keytarget == target here */
  if (!found_keyframe)
    best = 0;

  if (keytarget != target) {
    GST_LOG_OBJECT (ogg, "final seek to target %" GST_TIME_FORMAT,
        GST_TIME_ARGS (keytarget));

    /* last step, seek to the location of the keyframe */
    if (!do_binary_search (ogg, chain, begin, end, begintime, endtime,
            keytarget, &best, TRUE, serialno))
      goto seek_error;
  } else {
    /* seek back to previous position */
    GST_LOG_OBJECT (ogg, "keyframe on target");
    gst_ogg_demux_seek (ogg, best);
  }

done:
  if (keyframe) {
    if (segment->rate > 0.0)
      segment->time = keytarget;
    segment->position = keytarget - begintime;
  }

  *rchain = chain;

  return TRUE;

no_chains:
  {
    GST_DEBUG_OBJECT (ogg, "no chains");
    return FALSE;
  }
seek_error:
  {
    GST_DEBUG_OBJECT (ogg, "got a seek error");
    return FALSE;
  }
}

/* does not take ownership of the event */
static gboolean
gst_ogg_demux_perform_seek_pull (GstOggDemux * ogg, GstEvent * event)
{
  GstOggChain *chain = NULL;
  gboolean res;
  gboolean flush, accurate, keyframe;
  GstFormat format;
  gdouble rate;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  gboolean update;
  guint32 seqnum;
  GstEvent *tevent;

  if (event) {
    GST_DEBUG_OBJECT (ogg, "seek with event");

    gst_event_parse_seek (event, &rate, &format, &flags,
        &start_type, &start, &stop_type, &stop);

    /* we can only seek on time */
    if (format != GST_FORMAT_TIME) {
      GST_DEBUG_OBJECT (ogg, "can only seek on TIME");
      goto error;
    }
    seqnum = gst_event_get_seqnum (event);
  } else {
    GST_DEBUG_OBJECT (ogg, "seek without event");

    flags = 0;
    rate = 1.0;
    seqnum = gst_util_seqnum_next ();
  }

  GST_DEBUG_OBJECT (ogg, "seek, rate %g", rate);

  flush = flags & GST_SEEK_FLAG_FLUSH;
  accurate = flags & GST_SEEK_FLAG_ACCURATE;
  keyframe = flags & GST_SEEK_FLAG_KEY_UNIT;

  /* first step is to unlock the streaming thread if it is
   * blocked in a chain call, we do this by starting the flush. because
   * we cannot yet hold any streaming lock, we have to protect the chains
   * with their own lock. */
  if (flush) {
    gint i;

    tevent = gst_event_new_flush_start ();
    gst_event_set_seqnum (tevent, seqnum);

    gst_event_ref (tevent);
    gst_pad_push_event (ogg->sinkpad, tevent);

    GST_CHAIN_LOCK (ogg);
    for (i = 0; i < ogg->chains->len; i++) {
      GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i);
      gint j;

      for (j = 0; j < chain->streams->len; j++) {
        GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, j);

        gst_event_ref (tevent);
        gst_pad_push_event (GST_PAD (pad), tevent);
      }
    }
    GST_CHAIN_UNLOCK (ogg);

    gst_event_unref (tevent);
  } else {
    gst_pad_pause_task (ogg->sinkpad);
  }

  /* now grab the stream lock so that streaming cannot continue, for
   * non flushing seeks when the element is in PAUSED this could block
   * forever. */
  GST_PAD_STREAM_LOCK (ogg->sinkpad);

  if (event) {
    gst_segment_do_seek (&ogg->segment, rate, format, flags,
        start_type, start, stop_type, stop, &update);
  }

  GST_DEBUG_OBJECT (ogg, "segment positions set to %" GST_TIME_FORMAT "-%"
      GST_TIME_FORMAT, GST_TIME_ARGS (ogg->segment.start),
      GST_TIME_ARGS (ogg->segment.stop));

  /* we need to stop flushing on the srcpad as we're going to use it
   * next. We can do this as we have the STREAM lock now. */
  if (flush) {
    tevent = gst_event_new_flush_stop (TRUE);
    gst_event_set_seqnum (tevent, seqnum);
    gst_pad_push_event (ogg->sinkpad, tevent);
  }

  {
    gint i;

    /* reset all ogg streams now, need to do this from within the lock to
     * make sure the streaming thread is not messing with the stream */
    for (i = 0; i < ogg->chains->len; i++) {
      GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i);

      gst_ogg_chain_reset (chain);
    }
  }

  /* for reverse we will already seek accurately */
  res = gst_ogg_demux_do_seek (ogg, &ogg->segment, accurate, keyframe, &chain);

  /* seek failed, make sure we continue the current chain */
  if (!res) {
    GST_DEBUG_OBJECT (ogg, "seek failed");
    chain = ogg->current_chain;
  } else {
    GST_DEBUG_OBJECT (ogg, "seek success");
  }

  if (!chain)
    goto no_chain;

  /* now we have a new position, prepare for streaming again */
  {
    GstEvent *event;
    gint64 stop;
    gint64 start;
    gint64 position, begin_time;
    GstSegment segment;

    /* we have to send the flush to the old chain, not the new one */
    if (flush) {
      tevent = gst_event_new_flush_stop (TRUE);
      gst_event_set_seqnum (tevent, seqnum);
      gst_ogg_demux_send_event (ogg, tevent);
    }

    /* we need this to see how far inside the chain we need to start */
    if (chain->begin_time != GST_CLOCK_TIME_NONE)
      begin_time = chain->begin_time;
    else
      begin_time = 0;

    /* segment.start gives the start over all chains, we calculate the amount
     * of time into this chain we need to start */
    start = ogg->segment.start - begin_time;
    if (chain->segment_start != GST_CLOCK_TIME_NONE)
      start += chain->segment_start;

    if ((stop = ogg->segment.stop) == -1)
      stop = ogg->segment.duration;

    /* segment.stop gives the stop time over all chains, calculate the amount of
     * time we need to stop in this chain */
    if (stop != -1) {
      if (stop > begin_time)
        stop -= begin_time;
      else
        stop = 0;
      stop += chain->segment_start;
      /* we must stop when this chain ends and switch to the next chain to play
       * the remainder of the segment. */
      stop = MIN (stop, chain->segment_stop);
    }

    position = ogg->segment.position;
    if (chain->segment_start != GST_CLOCK_TIME_NONE)
      position += chain->segment_start;

    gst_segment_copy_into (&ogg->segment, &segment);

    /* create the segment event we are going to send out */
    if (ogg->segment.rate >= 0.0) {
      segment.start = position;
      segment.stop = stop;
    } else {
      segment.start = start;
      segment.stop = position;
    }
    event = gst_event_new_segment (&segment);
    gst_event_set_seqnum (event, seqnum);

    if (chain != ogg->current_chain) {
      /* switch to different chain, send segment on new chain */
      gst_ogg_demux_activate_chain (ogg, chain, event);
    } else {
      /* mark discont and send segment on current chain */
      gst_ogg_chain_mark_discont (chain);
      /* This event should be sent from the streaming thread (sink pad task) */
      if (ogg->newsegment)
        gst_event_unref (ogg->newsegment);
      ogg->newsegment = event;
    }

    /* notify start of new segment */
    if (ogg->segment.flags & GST_SEEK_FLAG_SEGMENT) {
      GstMessage *message;

      message = gst_message_new_segment_start (GST_OBJECT (ogg),
          GST_FORMAT_TIME, ogg->segment.position);
      gst_message_set_seqnum (message, seqnum);

      gst_element_post_message (GST_ELEMENT (ogg), message);
    }

    ogg->seqnum = seqnum;
    /* restart our task since it might have been stopped when we did the 
     * flush. */
    gst_pad_start_task (ogg->sinkpad, (GstTaskFunction) gst_ogg_demux_loop,
        ogg->sinkpad, NULL);
  }

  /* streaming can continue now */
  GST_PAD_STREAM_UNLOCK (ogg->sinkpad);

  return res;

  /* ERRORS */
error:
  {
    GST_DEBUG_OBJECT (ogg, "seek failed");
    return FALSE;
  }
no_chain:
  {
    GST_DEBUG_OBJECT (ogg, "no chain to seek in");
    GST_PAD_STREAM_UNLOCK (ogg->sinkpad);
    return FALSE;
  }
}

static gboolean
gst_ogg_demux_get_duration_push (GstOggDemux * ogg, int flags)
{
  /* In push mode, we get to the end of the stream to get the duration */
  gint64 position;
  GstEvent *sevent;

  /* A full Ogg page can be almost 64 KB. There's no guarantee that there'll be a
     granpos there, but it's fairly likely */
  position = ogg->push_byte_length - DURATION_CHUNK_OFFSET;
  if (position < 0)
    position = 0;

  GST_DEBUG_OBJECT (ogg,
      "Getting duration, seeking near the end, to %" G_GINT64_FORMAT, position);
  ogg->push_state = PUSH_DURATION;
  /* do not read the last byte */
  sevent = gst_event_new_seek (1.0, GST_FORMAT_BYTES, flags, GST_SEEK_TYPE_SET,
      position, GST_SEEK_TYPE_SET, ogg->push_byte_length - 1);
  gst_event_replace (&ogg->seek_event, sevent);
  gst_event_unref (sevent);
  g_mutex_lock (&ogg->seek_event_mutex);
  g_cond_broadcast (&ogg->seek_event_cond);
  g_mutex_unlock (&ogg->seek_event_mutex);
  return TRUE;
}

static gboolean
gst_ogg_demux_check_duration_push (GstOggDemux * ogg, GstSeekFlags flags,
    GstEvent * event)
{
  if (ogg->push_byte_length < 0) {
    GstPad *peer;

    GST_DEBUG_OBJECT (ogg, "Trying to find byte/time length");
    if ((peer = gst_pad_get_peer (ogg->sinkpad)) != NULL) {
      gint64 length;
      int res;

      res = gst_pad_query_duration (peer, GST_FORMAT_BYTES, &length);
      if (res && length > 0) {
        ogg->push_byte_length = length;
        GST_DEBUG_OBJECT (ogg,
            "File byte length %" G_GINT64_FORMAT, ogg->push_byte_length);
      } else {
        GST_DEBUG_OBJECT (ogg, "File byte length unknown, assuming live");
        ogg->push_disable_seeking = TRUE;
        gst_object_unref (peer);
        return TRUE;
      }
      res = gst_pad_query_duration (peer, GST_FORMAT_TIME, &length);
      gst_object_unref (peer);
      if (res && length >= 0) {
        ogg->push_time_length = length;
        GST_DEBUG_OBJECT (ogg, "File time length %" GST_TIME_FORMAT,
            GST_TIME_ARGS (ogg->push_time_length));
      } else if (!ogg->push_disable_seeking) {
        gboolean res;

        res = gst_ogg_demux_get_duration_push (ogg, flags);
        if (res) {
          GST_DEBUG_OBJECT (ogg,
              "File time length unknown, trying to determine");
          ogg->push_mode_seek_delayed_event = NULL;
          if (event) {
            GST_DEBUG_OBJECT (ogg,
                "Let me intercept this innocent looking seek request");
            ogg->push_mode_seek_delayed_event = gst_event_copy (event);
          }
          return FALSE;
        }
      }
    }
  }
  return TRUE;
}

static gboolean
gst_ogg_demux_perform_seek_push (GstOggDemux * ogg, GstEvent * event)
{
  gint bitrate;
  gboolean res = TRUE;
  GstFormat format;
  gdouble rate;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  GstEvent *sevent;
  GstOggChain *chain;
  gint64 best, best_time;
  gint i;

  GST_DEBUG_OBJECT (ogg, "Push mode seek request received");

  gst_event_parse_seek (event, &rate, &format, &flags,
      &start_type, &start, &stop_type, &stop);

  if (format != GST_FORMAT_TIME) {
    GST_DEBUG_OBJECT (ogg, "can only seek on TIME");
    goto error;
  }

  if (start_type != GST_SEEK_TYPE_SET) {
    GST_DEBUG_OBJECT (ogg, "can only seek to a SET target");
    goto error;
  }

  /* If stop is unset, make sure it is -1, as this value will be tested
     later to check whether stop is set or not */
  if (stop_type == GST_SEEK_TYPE_NONE)
    stop = -1;

  GST_DEBUG_OBJECT (ogg, "Push mode seek request: %" GST_TIME_FORMAT,
      GST_TIME_ARGS (start));

  chain = ogg->current_chain;
  if (!chain) {
    GST_WARNING_OBJECT (ogg, "No chain to seek on");
    goto error;
  }

  /* start accessing push_* members */
  GST_PUSH_LOCK (ogg);

  /* not if we disabled seeking (chained streams) */
  if (ogg->push_disable_seeking) {
    GST_DEBUG_OBJECT (ogg, "Seeking disabled");
    goto error_locked;
  }

  /* not when we're trying to work out duration */
  if (ogg->push_state == PUSH_DURATION) {
    GST_DEBUG_OBJECT (ogg, "Busy working out duration, try again later");
    goto error_locked;
  }

  /* actually, not if we're doing any seeking already */
  if (ogg->push_state != PUSH_PLAYING) {
    GST_DEBUG_OBJECT (ogg, "Already doing some seeking, try again later");
    goto error_locked;
  }

  /* on the first seek, get length if we can */
  if (!gst_ogg_demux_check_duration_push (ogg, flags, event)) {
    GST_PUSH_UNLOCK (ogg);
    return FALSE;
  }

  if (do_index_search (ogg, chain, 0, -1, 0, -1, start, &best, &best_time)) {
    /* the index gave some result */
    GST_DEBUG_OBJECT (ogg,
        "found offset %" G_GINT64_FORMAT " with time %" G_GUINT64_FORMAT,
        best, best_time);
  } else {
    if (ogg->push_time_length > 0) {
      /* if we know the time length, we know the full segment bitrate */
      GST_DEBUG_OBJECT (ogg, "Using real file bitrate");
      bitrate =
          gst_util_uint64_scale (ogg->push_byte_length, 8 * GST_SECOND,
          ogg->push_time_length);
    } else if (ogg->push_time_offset > 0) {
      /* get a first approximation using known bitrate to the current position */
      GST_DEBUG_OBJECT (ogg, "Using file bitrate so far");
      bitrate =
          gst_util_uint64_scale (ogg->push_byte_offset, 8 * GST_SECOND,
          ogg->push_time_offset);
    } else if (ogg->bitrate > 0) {
      /* nominal bitrate is better than nothing, even if it lies often */
      GST_DEBUG_OBJECT (ogg, "Using nominal bitrate");
      bitrate = ogg->bitrate;
    } else {
      /* meh */
      GST_DEBUG_OBJECT (ogg,
          "At stream start, and no nominal bitrate, using some random magic "
          "number to seed");
      /* the bisection, once started, should give us a better approximation */
      bitrate = 1000;
    }
    best = gst_util_uint64_scale (start, bitrate, 8 * GST_SECOND);
  }

  /* offset by typical page length, and ensure our best guess is within
     reasonable bounds */
  best -= ogg->chunk_size;
  if (best < 0)
    best = 0;
  if (ogg->push_byte_length > 0 && best >= ogg->push_byte_length)
    best = ogg->push_byte_length - 1;

  /* set up bisection search */
  ogg->push_offset0 = 0;
  ogg->push_offset1 = ogg->push_byte_length - 1;
  ogg->push_time0 = ogg->push_start_time;
  ogg->push_time1 = ogg->push_time_length;
  ogg->seqnum = gst_event_get_seqnum (event);
  ogg->push_seek_time_target = start;
  ogg->push_prev_seek_time = GST_CLOCK_TIME_NONE;
  ogg->push_seek_time_original_target = start;
  ogg->push_seek_time_original_stop = stop;
  ogg->push_state = PUSH_BISECT1;
  ogg->seek_secant = FALSE;
  ogg->seek_undershot = FALSE;

  if (flags & GST_SEEK_FLAG_FLUSH) {
    /* reset pad push mode seeking state */
    for (i = 0; i < chain->streams->len; i++) {
      GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
      pad->push_kf_time = GST_CLOCK_TIME_NONE;
      pad->push_sync_time = GST_CLOCK_TIME_NONE;
    }
  }

  GST_DEBUG_OBJECT (ogg,
      "Setting up bisection search for %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT
      " (time %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT ")", ogg->push_offset0,
      ogg->push_offset1, GST_TIME_ARGS (ogg->push_time0),
      GST_TIME_ARGS (ogg->push_time1));
  GST_DEBUG_OBJECT (ogg,
      "Target time is %" GST_TIME_FORMAT ", best first guess is %"
      G_GINT64_FORMAT, GST_TIME_ARGS (ogg->push_seek_time_target), best);

  ogg->push_seek_rate = rate;
  ogg->push_seek_flags = flags;
  ogg->push_mode_seek_delayed_event = NULL;
  ogg->push_bisection_steps[0] = 1;
  ogg->push_bisection_steps[1] = 0;
  sevent = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags,
      start_type, best, GST_SEEK_TYPE_NONE, -1);
  gst_event_set_seqnum (sevent, gst_event_get_seqnum (event));

  gst_event_replace (&ogg->seek_event, sevent);
  gst_event_unref (sevent);
  GST_PUSH_UNLOCK (ogg);
  g_mutex_lock (&ogg->seek_event_mutex);
  g_cond_broadcast (&ogg->seek_event_cond);
  g_mutex_unlock (&ogg->seek_event_mutex);

  return res;

  /* ERRORS */
error:
  {
    GST_DEBUG_OBJECT (ogg, "seek failed");
    return FALSE;
  }

error_locked:
  GST_PUSH_UNLOCK (ogg);
  goto error;
}

static gboolean
gst_ogg_demux_perform_seek (GstOggDemux * ogg, GstEvent * event)
{
  gboolean res;

  if (ogg->pullmode) {
    res = gst_ogg_demux_perform_seek_pull (ogg, event);
  } else {
    res = gst_ogg_demux_perform_seek_push (ogg, event);
  }
  return res;
}


/* finds each bitstream link one at a time using a bisection search
 * (has to begin by knowing the offset of the lb's initial page).
 * Recurses for each link so it can alloc the link storage after
 * finding them all, then unroll and fill the cache at the same time
 */
static GstFlowReturn
gst_ogg_demux_bisect_forward_serialno (GstOggDemux * ogg,
    gint64 begin, gint64 searched, gint64 end, GstOggChain * chain, glong m)
{
  gint64 endsearched = end;
  gint64 next = end;
  ogg_page og;
  GstFlowReturn ret;
  gint64 offset;
  GstOggChain *nextchain;

  GST_LOG_OBJECT (ogg,
      "bisect begin: %" G_GINT64_FORMAT ", searched: %" G_GINT64_FORMAT
      ", end %" G_GINT64_FORMAT ", chain: %p", begin, searched, end, chain);

  /* the below guards against garbage seperating the last and
   * first pages of two links. */
  while (searched < endsearched) {
    gint64 bisect;

    if (endsearched - searched < ogg->chunk_size) {
      bisect = searched;
    } else {
      bisect = (searched + endsearched) / 2;
    }

    gst_ogg_demux_seek (ogg, bisect);
    ret = gst_ogg_demux_get_next_page (ogg, &og, -1, &offset);

    if (ret == GST_FLOW_EOS) {
      endsearched = bisect;
    } else if (ret == GST_FLOW_OK) {
      guint32 serial = ogg_page_serialno (&og);

      if (!gst_ogg_chain_has_stream (chain, serial)) {
        endsearched = bisect;
        next = offset;
      } else {
        searched = offset + og.header_len + og.body_len;
      }
    } else
      return ret;
  }

  GST_LOG_OBJECT (ogg, "current chain ends at %" G_GINT64_FORMAT, searched);

  chain->end_offset = searched;
  ret = gst_ogg_demux_read_end_chain (ogg, chain);
  if (ret != GST_FLOW_OK)
    return ret;

  GST_LOG_OBJECT (ogg, "found begin at %" G_GINT64_FORMAT, next);

  gst_ogg_demux_seek (ogg, next);
  ret = gst_ogg_demux_read_chain (ogg, &nextchain);
  if (ret == GST_FLOW_EOS) {
    nextchain = NULL;
    ret = GST_FLOW_OK;
    GST_LOG_OBJECT (ogg, "no next chain");
  } else if (ret != GST_FLOW_OK)
    goto done;

  if (searched < end && nextchain != NULL) {
    ret = gst_ogg_demux_bisect_forward_serialno (ogg, next, ogg->offset,
        end, nextchain, m + 1);
    if (ret != GST_FLOW_OK)
      goto done;
  }
  GST_LOG_OBJECT (ogg, "adding chain %p", chain);

  g_array_insert_val (ogg->chains, 0, chain);

done:
  return ret;
}

/* read a chain from the ogg file. This code will
 * read all BOS pages and will create and return a GstOggChain 
 * structure with the results. 
 * 
 * This function will also read N pages from each stream in the
 * chain and submit them to the internal ogg stream parser/mapper
 * until we know the timestamp of the first page in the chain.
 */
static GstFlowReturn
gst_ogg_demux_read_chain (GstOggDemux * ogg, GstOggChain ** res_chain)
{
  GstFlowReturn ret;
  GstOggChain *chain = NULL;
  gint64 offset = ogg->offset;
  ogg_page og;
  gboolean done;
  gint i;

  GST_LOG_OBJECT (ogg, "reading chain at %" G_GINT64_FORMAT, offset);

  /* first read the BOS pages, detect the stream types, create the internal
   * stream mappers, send data to them. */
  while (TRUE) {
    GstOggPad *pad;
    guint32 serial;

    ret = gst_ogg_demux_get_next_page (ogg, &og, -1, NULL);
    if (ret != GST_FLOW_OK) {
      if (ret == GST_FLOW_EOS) {
        GST_DEBUG_OBJECT (ogg, "Reached EOS, done reading end chain");
      } else {
        GST_WARNING_OBJECT (ogg, "problem reading BOS page: ret=%d", ret);
      }
      break;
    }
    if (!ogg_page_bos (&og)) {
      GST_INFO_OBJECT (ogg, "page is not BOS page, all streams identified");
      /* if we did not find a chain yet, assume this is a bogus stream and
       * ignore it */
      if (!chain) {
        GST_WARNING_OBJECT (ogg, "No chain found, no Ogg data in stream ?");
        ret = GST_FLOW_EOS;
      }
      break;
    }

    if (chain == NULL) {
      chain = gst_ogg_chain_new (ogg);
      chain->offset = offset;
    }

    serial = ogg_page_serialno (&og);
    if (gst_ogg_chain_get_stream (chain, serial) != NULL) {
      GST_WARNING_OBJECT (ogg,
          "found serial %08x BOS page twice, ignoring", serial);
      continue;
    }

    pad = gst_ogg_chain_new_stream (chain, serial);
    gst_ogg_pad_submit_page (pad, &og);
  }

  if (ret != GST_FLOW_OK || chain == NULL) {
    if (ret == GST_FLOW_OK) {
      GST_WARNING_OBJECT (ogg, "no chain was found");
      ret = GST_FLOW_ERROR;
    } else if (ret != GST_FLOW_EOS) {
      GST_WARNING_OBJECT (ogg, "failed to read chain");
    } else {
      GST_DEBUG_OBJECT (ogg, "done reading chains");
    }
    if (chain) {
      gst_ogg_chain_free (chain);
    }
    if (res_chain)
      *res_chain = NULL;
    return ret;
  }

  chain->have_bos = TRUE;
  GST_INFO_OBJECT (ogg, "read bos pages, ");

  /* now read pages until each ogg stream mapper has figured out the
   * timestamp of the first packet in the chain */

  /* save the offset to the first non bos page in the chain: if searching for
   * pad->first_time we read past the end of the chain, we'll seek back to this
   * position
   */
  offset = ogg->offset;

  done = FALSE;
  while (!done) {
    guint32 serial;
    gboolean known_serial = FALSE;
    GstFlowReturn ret;

    serial = ogg_page_serialno (&og);
    done = TRUE;
    for (i = 0; i < chain->streams->len; i++) {
      GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

      GST_LOG_OBJECT (ogg,
          "serial %08x time %" GST_TIME_FORMAT,
          pad->map.serialno, GST_TIME_ARGS (pad->start_time));

      if (pad->map.serialno == serial) {
        known_serial = TRUE;

        /* submit the page now, this will fill in the start_time when the
         * internal stream mapper finds it */
        gst_ogg_pad_submit_page (pad, &og);

        if (!pad->map.is_skeleton && pad->start_time == -1
            && ogg_page_eos (&og)) {
          /* got EOS on a pad before we could find its start_time.
           * We have no chance of finding a start_time for every pad so
           * stop searching for the other start_time(s).
           */
          done = TRUE;
          break;
        }
      }
      /* the timestamp will be filled in when we submit the pages */
      if (!pad->map.is_sparse)
        done &= (pad->start_time != GST_CLOCK_TIME_NONE);

      GST_LOG_OBJECT (ogg, "done %08x now %d", pad->map.serialno, done);
    }

    /* we read a page not belonging to the current chain: seek back to the
     * beginning of the chain
     */
    if (!known_serial) {
      GST_LOG_OBJECT (ogg, "unknown serial %08x", serial);
      gst_ogg_demux_seek (ogg, offset);
      break;
    }

    if (!done) {
      ret = gst_ogg_demux_get_next_page (ogg, &og, -1, NULL);
      if (ret != GST_FLOW_OK)
        break;
    }
  }
  GST_LOG_OBJECT (ogg, "done reading chain");

  if (res_chain)
    *res_chain = chain;

  return GST_FLOW_OK;
}

/* read the last pages from the ogg stream to get the final
 * page end_offsets.
 */
static GstFlowReturn
gst_ogg_demux_read_end_chain (GstOggDemux * ogg, GstOggChain * chain)
{
  gint64 begin = chain->end_offset;
  gint64 end = begin;
  gint64 last_granule = -1;
  GstOggPad *last_pad = NULL;
  GstFlowReturn ret;
  gboolean done = FALSE;
  ogg_page og;
  gint i;

  while (!done) {
    begin -= ogg->chunk_size;
    if (begin < 0)
      begin = 0;

    gst_ogg_demux_seek (ogg, begin);

    /* now continue reading until we run out of data, if we find a page
     * start, we save it. It might not be the final page as there could be
     * another page after this one. */
    while (ogg->offset < end) {
      ret = gst_ogg_demux_get_next_page (ogg, &og, end - ogg->offset, NULL);

      if (ret == GST_FLOW_LIMIT)
        break;
      if (ret != GST_FLOW_OK)
        return ret;

      for (i = 0; i < chain->streams->len; i++) {
        GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

        if (pad->map.is_skeleton)
          continue;

        if (pad->map.serialno == ogg_page_serialno (&og)) {
          gint64 granulepos = ogg_page_granulepos (&og);

          if (granulepos != -1) {
            last_granule = granulepos;
            last_pad = pad;
            done = TRUE;
          }
          break;
        }
      }
    }
  }

  if (last_pad) {
    chain->segment_stop =
        gst_ogg_stream_get_end_time_for_granulepos (&last_pad->map,
        last_granule);
  } else {
    chain->segment_stop = GST_CLOCK_TIME_NONE;
  }

  GST_INFO ("segment stop %" G_GUINT64_FORMAT ", for last granule %"
      G_GUINT64_FORMAT, chain->segment_stop, last_granule);

  return GST_FLOW_OK;
}

/* find a pad with a given serial number
 */
static GstOggPad *
gst_ogg_demux_find_pad (GstOggDemux * ogg, guint32 serialno)
{
  GstOggPad *pad;
  gint i;

  /* first look in building chain if any */
  if (ogg->building_chain) {
    pad = gst_ogg_chain_get_stream (ogg->building_chain, serialno);
    if (pad)
      return pad;
  }

  /* then look in current chain if any */
  if (ogg->current_chain) {
    pad = gst_ogg_chain_get_stream (ogg->current_chain, serialno);
    if (pad)
      return pad;
  }

  for (i = 0; i < ogg->chains->len; i++) {
    GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i);

    pad = gst_ogg_chain_get_stream (chain, serialno);
    if (pad)
      return pad;
  }
  return NULL;
}

/* find a chain with a given serial number
 */
static GstOggChain *
gst_ogg_demux_find_chain (GstOggDemux * ogg, guint32 serialno)
{
  GstOggPad *pad;

  pad = gst_ogg_demux_find_pad (ogg, serialno);
  if (pad) {
    return pad->chain;
  }
  return NULL;
}

/* returns TRUE if all streams have valid start time */
static gboolean
gst_ogg_demux_collect_chain_info (GstOggDemux * ogg, GstOggChain * chain)
{
  gboolean res = TRUE;

  chain->total_time = GST_CLOCK_TIME_NONE;
  GST_DEBUG_OBJECT (ogg, "trying to collect chain info");

  /* see if we have a start time on all streams */
  chain->segment_start = gst_ogg_demux_collect_start_time (ogg, chain);

  if (chain->segment_start == G_MAXUINT64) {
    /* not yet, stream some more data */
    res = FALSE;
  } else if (chain->segment_stop != GST_CLOCK_TIME_NONE) {
    /* we can calculate a total time */
    chain->total_time = chain->segment_stop - chain->segment_start;
  }

  GST_DEBUG ("total time %" G_GUINT64_FORMAT, chain->total_time);

  GST_DEBUG_OBJECT (ogg, "return %d", res);

  return res;
}

static void
gst_ogg_demux_collect_info (GstOggDemux * ogg)
{
  gint i;

  /* collect all info */
  ogg->total_time = 0;

  for (i = 0; i < ogg->chains->len; i++) {
    GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i);

    chain->begin_time = ogg->total_time;

    gst_ogg_demux_collect_chain_info (ogg, chain);

    ogg->total_time += chain->total_time;
  }
  ogg->segment.duration = ogg->total_time;
}

/* find all the chains in the ogg file, this reads the first and
 * last page of the ogg stream, if they match then the ogg file has
 * just one chain, else we do a binary search for all chains.
 */
static GstFlowReturn
gst_ogg_demux_find_chains (GstOggDemux * ogg)
{
  ogg_page og;
  GstPad *peer;
  gboolean res;
  guint32 serialno;
  GstOggChain *chain;
  GstFlowReturn ret;

  /* get peer to figure out length */
  if ((peer = gst_pad_get_peer (ogg->sinkpad)) == NULL)
    goto no_peer;

  /* find length to read last page, we store this for later use. */
  res = gst_pad_query_duration (peer, GST_FORMAT_BYTES, &ogg->length);
  gst_object_unref (peer);
  if (!res || ogg->length <= 0)
    goto no_length;

  GST_DEBUG_OBJECT (ogg, "file length %" G_GINT64_FORMAT, ogg->length);

  /* read chain from offset 0, this is the first chain of the
   * ogg file. */
  gst_ogg_demux_seek (ogg, 0);
  ret = gst_ogg_demux_read_chain (ogg, &chain);
  if (ret != GST_FLOW_OK) {
    if (ret == GST_FLOW_FLUSHING)
      goto flushing;
    else
      goto no_first_chain;
  }

  /* read page from end offset, we use this page to check if its serial
   * number is contained in the first chain. If this is the case then
   * this ogg is not a chained ogg and we can skip the scanning. */
  gst_ogg_demux_seek (ogg, ogg->length);
  ret = gst_ogg_demux_get_prev_page (ogg, &og, NULL);
  if (ret != GST_FLOW_OK)
    goto no_last_page;

  serialno = ogg_page_serialno (&og);

  if (!gst_ogg_chain_has_stream (chain, serialno)) {
    /* the last page is not in the first stream, this means we should
     * find all the chains in this chained ogg. */
    ret =
        gst_ogg_demux_bisect_forward_serialno (ogg, 0, 0, ogg->length, chain,
        0);
  } else {
    /* we still call this function here but with an empty range so that
     * we can reuse the setup code in this routine. */
    ret =
        gst_ogg_demux_bisect_forward_serialno (ogg, 0, ogg->length,
        ogg->length, chain, 0);
  }
  if (ret != GST_FLOW_OK)
    goto done;

  /* all fine, collect and print */
  gst_ogg_demux_collect_info (ogg);

  /* dump our chains and streams */
  gst_ogg_print (ogg);

done:
  return ret;

  /*** error cases ***/
no_peer:
  {
    GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, (NULL), ("we don't have a peer"));
    return GST_FLOW_NOT_LINKED;
  }
no_length:
  {
    GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, (NULL), ("can't get file length"));
    return GST_FLOW_NOT_SUPPORTED;
  }
no_first_chain:
  {
    GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, (NULL), ("can't get first chain"));
    return GST_FLOW_ERROR;
  }
no_last_page:
  {
    GST_DEBUG_OBJECT (ogg, "can't get last page");
    if (chain)
      gst_ogg_chain_free (chain);
    return ret;
  }
flushing:
  {
    GST_DEBUG_OBJECT (ogg, "Flushing, can't read chain");
    return GST_FLOW_FLUSHING;
  }
}

static void
gst_ogg_demux_update_chunk_size (GstOggDemux * ogg, ogg_page * page)
{
  long size = page->header_len + page->body_len;
  long chunk_size = size * 2;
  if (chunk_size > ogg->chunk_size) {
    GST_LOG_OBJECT (ogg, "Updating chunk size to %ld", chunk_size);
    ogg->chunk_size = chunk_size;
  }
}

static GstFlowReturn
gst_ogg_demux_handle_page (GstOggDemux * ogg, ogg_page * page, gboolean discont)
{
  GstOggPad *pad;
  gint64 granule;
  guint32 serialno;
  GstFlowReturn result = GST_FLOW_OK;

  serialno = ogg_page_serialno (page);
  granule = ogg_page_granulepos (page);

  gst_ogg_demux_update_chunk_size (ogg, page);

  GST_LOG_OBJECT (ogg,
      "processing ogg page (serial %08x, "
      "pageno %ld, granulepos %" G_GINT64_FORMAT ", bos %d)", serialno,
      ogg_page_pageno (page), granule, ogg_page_bos (page));

  if (ogg_page_bos (page)) {
    GstOggChain *chain;

    /* first page */
    /* see if we know about the chain already */
    chain = gst_ogg_demux_find_chain (ogg, serialno);
    if (chain) {
      GstEvent *event;
      gint64 start = 0;
      GstSegment segment;

      if (chain->segment_start != GST_CLOCK_TIME_NONE)
        start = chain->segment_start;

      /* create the newsegment event we are going to send out */
      gst_segment_copy_into (&ogg->segment, &segment);
      segment.start = start;
      segment.stop = chain->segment_stop;
      segment.time = chain->begin_time;
      segment.base += chain->begin_time;
      event = gst_event_new_segment (&segment);
      gst_event_set_seqnum (event, ogg->seqnum);

      GST_DEBUG_OBJECT (ogg,
          "segment: start %" GST_TIME_FORMAT ", stop %" GST_TIME_FORMAT
          ", time %" GST_TIME_FORMAT, GST_TIME_ARGS (start),
          GST_TIME_ARGS (chain->segment_stop),
          GST_TIME_ARGS (chain->begin_time));

      /* activate it as it means we have a non-header, this will also deactivate
       * the currently running chain. */
      gst_ogg_demux_activate_chain (ogg, chain, event);
      pad = gst_ogg_demux_find_pad (ogg, serialno);
    } else {
      GstClockTime chain_time;
      gint64 current_time;

      /* this can only happen in push mode */
      if (ogg->pullmode)
        goto unknown_chain;

      current_time = ogg->segment.position;

      /* time of new chain is current time */
      chain_time = current_time;

      if (ogg->building_chain == NULL) {
        GstOggChain *newchain;

        newchain = gst_ogg_chain_new (ogg);
        newchain->offset = 0;
        /* set new chain begin time aligned with end time of old chain */
        newchain->begin_time = chain_time;
        GST_DEBUG_OBJECT (ogg, "new chain, begin time %" GST_TIME_FORMAT,
            GST_TIME_ARGS (chain_time));

        /* and this is the one we are building now */
        ogg->building_chain = newchain;
      }
      pad = gst_ogg_chain_new_stream (ogg->building_chain, serialno);
    }
  } else {
    pad = gst_ogg_demux_find_pad (ogg, serialno);
  }
  if (pad) {
    /* Reset granule interpolation if chaining in reverse (discont = TRUE) */
    if (discont)
      pad->current_granule = -1;

    result = gst_ogg_pad_submit_page (pad, page);
  } else {
    GST_PUSH_LOCK (ogg);
    if (!ogg->pullmode && !ogg->push_disable_seeking) {
      /* no pad while probing for duration, we must have a chained stream,
         and we don't support them, so back off */
      GST_INFO_OBJECT (ogg, "We seem to have a chained stream, we won't seek");
      if (ogg->push_state == PUSH_DURATION) {
        GstFlowReturn res;

        res = gst_ogg_demux_seek_back_after_push_duration_check_unlock (ogg);
        /* Call to function above unlocks, relock */
        GST_PUSH_LOCK (ogg);
        if (res != GST_FLOW_OK)
          return res;
      }

      /* only once we seeked back */
      ogg->push_disable_seeking = TRUE;
    } else {
      GST_PUSH_UNLOCK (ogg);
      /* no pad. This means an ogg page without bos has been seen for this
       * serialno. we just ignore it but post a warning... */
      GST_ELEMENT_WARNING (ogg, STREAM, DECODE,
          (NULL), ("unknown ogg pad for serial %08x detected", serialno));
      return GST_FLOW_OK;
    }
    GST_PUSH_UNLOCK (ogg);
  }
  return result;

  /* ERRORS */
unknown_chain:
  {
    GST_ELEMENT_ERROR (ogg, STREAM, DECODE,
        (NULL), ("unknown ogg chain for serial %08x detected", serialno));
    return GST_FLOW_ERROR;
  }
}

/* streaming mode, receive a buffer, parse it, create pads for
 * the serialno, submit pages and packets to the oggpads
 */
static GstFlowReturn
gst_ogg_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstOggDemux *ogg;
  gint ret = 0;
  GstFlowReturn result = GST_FLOW_OK;
  gboolean drop;

  ogg = GST_OGG_DEMUX (parent);

  GST_PUSH_LOCK (ogg);
  drop = (ogg->seek_event_drop_till > 0);
  GST_PUSH_UNLOCK (ogg);
  if (drop) {
    GST_DEBUG_OBJECT (ogg, "Dropping buffer because we have a pending seek");
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }

  GST_DEBUG_OBJECT (ogg, "enter");
  result = gst_ogg_demux_submit_buffer (ogg, buffer);
  if (result < 0) {
    GST_DEBUG_OBJECT (ogg, "gst_ogg_demux_submit_buffer returned %d", result);
  }

  while (result == GST_FLOW_OK) {
    ogg_page page;

    ret = ogg_sync_pageout (&ogg->sync, &page);
    if (ret == 0)
      /* need more data */
      break;
    if (ret == -1) {
      /* discontinuity in the pages */
      GST_DEBUG_OBJECT (ogg, "discont in page found, continuing");
    } else {
      result = gst_ogg_demux_handle_page (ogg, &page, FALSE);
      if (result < 0) {
        GST_DEBUG_OBJECT (ogg, "gst_ogg_demux_handle_page returned %d", result);
      }
    }
  }
  if (ret == 0 || result == GST_FLOW_OK) {
    gst_ogg_demux_sync_streams (ogg);
  }
  GST_DEBUG_OBJECT (ogg, "leave with %d", result);
  return result;
}

static gboolean
gst_ogg_demux_send_event (GstOggDemux * ogg, GstEvent * event)
{
  GstOggChain *chain = ogg->current_chain;
  gboolean event_sent = FALSE;
  gboolean res = TRUE;

  if (!chain)
    chain = ogg->building_chain;

  if (chain) {
    gint i;

    for (i = 0; i < chain->streams->len; i++) {
      GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);

      gst_event_ref (event);
      GST_DEBUG_OBJECT (pad, "Pushing event %" GST_PTR_FORMAT, event);
      res &= gst_pad_push_event (GST_PAD (pad), event);
      if (pad->added)
        event_sent = TRUE;
    }
  }

  gst_event_unref (event);

  if (!event_sent && GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
    GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, (NULL),
        ("EOS before finding a chain"));
  }

  return res;
}

static GstFlowReturn
gst_ogg_demux_combine_flows (GstOggDemux * ogg, GstOggPad * pad,
    GstFlowReturn ret)
{
  /* store the value */
  pad->last_ret = ret;
  pad->is_eos = (ret == GST_FLOW_EOS);

  return gst_flow_combiner_update_pad_flow (ogg->flowcombiner,
      GST_PAD_CAST (pad), ret);
}

static GstFlowReturn
gst_ogg_demux_loop_forward (GstOggDemux * ogg)
{
  GstFlowReturn ret;
  GstBuffer *buffer = NULL;

  if (ogg->offset == ogg->length) {
    GST_LOG_OBJECT (ogg, "no more data to pull %" G_GINT64_FORMAT
        " == %" G_GINT64_FORMAT, ogg->offset, ogg->length);
    ret = GST_FLOW_EOS;
    goto done;
  }

  GST_LOG_OBJECT (ogg, "pull data %" G_GINT64_FORMAT, ogg->offset);
  ret =
      gst_pad_pull_range (ogg->sinkpad, ogg->offset, ogg->chunk_size, &buffer);
  if (ret != GST_FLOW_OK) {
    GST_LOG_OBJECT (ogg, "Failed pull_range");
    goto done;
  }

  ogg->offset += gst_buffer_get_size (buffer);

  if (G_UNLIKELY (ogg->newsegment)) {
    gst_ogg_demux_send_event (ogg, ogg->newsegment);
    ogg->newsegment = NULL;
  }

  ret = gst_ogg_demux_chain (ogg->sinkpad, GST_OBJECT_CAST (ogg), buffer);
  if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS) {
    GST_LOG_OBJECT (ogg, "Failed demux_chain");
  }

done:
  return ret;
}

/* reverse mode.
 *
 * We read the pages backwards and send the packets forwards. The first packet
 * in the page will be pushed with the DISCONT flag set.
 *
 * Special care has to be taken for continued pages, which we can only decode
 * when we have the previous page(s).
 */
static GstFlowReturn
gst_ogg_demux_loop_reverse (GstOggDemux * ogg)
{
  GstFlowReturn ret;
  ogg_page page;
  gint64 offset;

  if (ogg->offset == 0) {
    GST_LOG_OBJECT (ogg, "no more data to pull %" G_GINT64_FORMAT
        " == 0", ogg->offset);
    ret = GST_FLOW_EOS;
    goto done;
  }

  GST_LOG_OBJECT (ogg, "read page from %" G_GINT64_FORMAT, ogg->offset);
  ret = gst_ogg_demux_get_prev_page (ogg, &page, &offset);
  if (ret != GST_FLOW_OK)
    goto done;

  ogg->offset = offset;

  if (G_UNLIKELY (ogg->newsegment)) {
    gst_ogg_demux_send_event (ogg, ogg->newsegment);
    ogg->newsegment = NULL;
  }

  GST_LOG_OBJECT (ogg, "Handling page at offset %" G_GINT64_FORMAT,
      ogg->offset);
  ret = gst_ogg_demux_handle_page (ogg, &page, TRUE);

done:
  return ret;
}

static void
gst_ogg_demux_sync_streams (GstOggDemux * ogg)
{
  GstClockTime cur;
  GstOggChain *chain;
  guint i;

  chain = ogg->current_chain;
  cur = ogg->segment.position;
  if (chain == NULL || cur == -1)
    return;

  for (i = 0; i < chain->streams->len; i++) {
    GstOggPad *stream = g_array_index (chain->streams, GstOggPad *, i);

    /* Theoretically, we should be doing this for all streams, so we're doing
     * it, but it might break things break things for wrongly-muxed streams
     * (like we used to produce once) */
    if ( /*stream->map.is_sparse && */ stream->position != GST_CLOCK_TIME_NONE) {

      /* Does this stream lag? Random threshold of 2 seconds */
      if (GST_CLOCK_DIFF (stream->position, cur) > (2 * GST_SECOND)) {
        GST_DEBUG_OBJECT (stream, "synchronizing stream with others by "
            "advancing time from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
            GST_TIME_ARGS (stream->position), GST_TIME_ARGS (cur));

        stream->position = cur;

        gst_pad_push_event (GST_PAD_CAST (stream),
            gst_event_new_gap (stream->position, cur - stream->position));
      }
    }
  }
}

/* random access code
 *
 * - first find all the chains and streams by scanning the file.
 * - then get and chain buffers, just like the streaming case.
 * - when seeking, we can use the chain info to perform the seek.
 */
static void
gst_ogg_demux_loop (GstOggPad * pad)
{
  GstOggDemux *ogg;
  GstFlowReturn ret;

  ogg = GST_OGG_DEMUX (GST_OBJECT_PARENT (pad));

  if (ogg->need_chains) {
    gboolean res;

    /* this is the only place where we write chains and thus need to lock. */
    GST_CHAIN_LOCK (ogg);
    ret = gst_ogg_demux_find_chains (ogg);
    GST_CHAIN_UNLOCK (ogg);
    if (ret != GST_FLOW_OK)
      goto chain_read_failed;

    ogg->need_chains = FALSE;

    GST_OBJECT_LOCK (ogg);
    ogg->running = TRUE;
    GST_OBJECT_UNLOCK (ogg);

    /* and seek to configured positions without FLUSH */
    res = gst_ogg_demux_perform_seek_pull (ogg, NULL);

    if (!res)
      goto seek_failed;
  }

  if (ogg->segment.rate >= 0.0)
    ret = gst_ogg_demux_loop_forward (ogg);
  else
    ret = gst_ogg_demux_loop_reverse (ogg);

  if (ret != GST_FLOW_OK)
    goto pause;

  gst_ogg_demux_sync_streams (ogg);
  return;

  /* ERRORS */
chain_read_failed:
  {
    /* error was posted */
    goto pause;
  }
seek_failed:
  {
    gboolean flushing;

    GST_OBJECT_LOCK (pad);
    flushing = GST_PAD_IS_FLUSHING (pad);
    GST_OBJECT_UNLOCK (pad);
    if (flushing) {
      ret = GST_FLOW_FLUSHING;
    } else {
      GST_ELEMENT_FLOW_ERROR (ogg, ret);
      ret = GST_FLOW_ERROR;
    }
    goto pause;
  }
pause:
  {
    const gchar *reason = gst_flow_get_name (ret);
    GstEvent *event = NULL;

    GST_LOG_OBJECT (ogg, "pausing task, reason %s", reason);
    gst_pad_pause_task (ogg->sinkpad);

    if (ret == GST_FLOW_EOS) {
      /* perform EOS logic */
      if (ogg->segment.flags & GST_SEEK_FLAG_SEGMENT) {
        gint64 stop;
        GstMessage *message;

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

        GST_LOG_OBJECT (ogg, "Sending segment done, at end of segment");
        message =
            gst_message_new_segment_done (GST_OBJECT (ogg), GST_FORMAT_TIME,
            stop);
        gst_message_set_seqnum (message, ogg->seqnum);

        gst_element_post_message (GST_ELEMENT (ogg), message);

        event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
        gst_event_set_seqnum (event, ogg->seqnum);
        gst_ogg_demux_send_event (ogg, event);
        event = NULL;
      } else {
        /* normal playback, send EOS to all linked pads */
        GST_LOG_OBJECT (ogg, "Sending EOS, at end of stream");
        event = gst_event_new_eos ();
      }
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
      GST_ELEMENT_FLOW_ERROR (ogg, ret);
      event = gst_event_new_eos ();
    }

    /* For wrong-state we still want to pause the task and stop
     * but no error message or other things are necessary.
     * wrong-state is no real error and will be caused by flushing,
     * e.g. because of a flushing seek.
     */
    if (event) {
      /* guard against corrupt/truncated files, where one can hit EOS
         before prerolling is done and a chain created. If we have no
         chain to send the event to, error out. */
      if (ogg->current_chain || ogg->building_chain) {
        gst_event_set_seqnum (event, ogg->seqnum);
        gst_ogg_demux_send_event (ogg, event);
      } else {
        gst_event_unref (event);
        GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, (NULL),
            ("EOS before finding a chain"));
      }
    }
    return;
  }
}

/* The sink pad task function for push mode.
 * It just sends any seek events queued by the streaming thread.
 */
static gpointer
gst_ogg_demux_loop_push (GstOggDemux * ogg)
{
  GstEvent *event = NULL;

  g_mutex_lock (&ogg->seek_event_mutex);
  /* Inform other threads that we started */
  ogg->seek_thread_started = TRUE;
  g_cond_broadcast (&ogg->thread_started_cond);


  while (!ogg->seek_event_thread_stop) {

    while (!ogg->seek_event_thread_stop) {
      GST_PUSH_LOCK (ogg);
      event = ogg->seek_event;
      ogg->seek_event = NULL;
      if (event)
        ogg->seek_event_drop_till = gst_event_get_seqnum (event);
      GST_PUSH_UNLOCK (ogg);

      if (event)
        break;

      g_cond_wait (&ogg->seek_event_cond, &ogg->seek_event_mutex);
    }

    if (ogg->seek_event_thread_stop) {
      break;
    }
    g_assert (event);

    g_mutex_unlock (&ogg->seek_event_mutex);

    GST_DEBUG_OBJECT (ogg->sinkpad, "Pushing event %" GST_PTR_FORMAT, event);
    if (!gst_pad_push_event (ogg->sinkpad, event)) {
      GST_WARNING_OBJECT (ogg, "Failed to push event");
      GST_PUSH_LOCK (ogg);
      if (!ogg->pullmode) {
        ogg->push_state = PUSH_PLAYING;
        ogg->push_disable_seeking = TRUE;
      }
      GST_PUSH_UNLOCK (ogg);
    } else {
      GST_DEBUG_OBJECT (ogg->sinkpad, "Pushed event ok");
    }

    g_mutex_lock (&ogg->seek_event_mutex);
  }

  g_mutex_unlock (&ogg->seek_event_mutex);

  gst_object_unref (ogg);
  return NULL;
}

static void
gst_ogg_demux_clear_chains (GstOggDemux * ogg)
{
  gint i;

  gst_ogg_demux_deactivate_current_chain (ogg);

  GST_CHAIN_LOCK (ogg);
  for (i = 0; i < ogg->chains->len; i++) {
    GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i);

    if (chain == ogg->current_chain)
      ogg->current_chain = NULL;
    if (chain == ogg->building_chain)
      ogg->building_chain = NULL;
    gst_ogg_chain_free (chain);
  }
  ogg->chains = g_array_set_size (ogg->chains, 0);
  if (ogg->current_chain != NULL) {
    GST_FIXME_OBJECT (ogg, "current chain was tracked in existing chains !");
    gst_ogg_chain_free (ogg->current_chain);
    ogg->current_chain = NULL;
  }
  if (ogg->building_chain != NULL) {
    GST_FIXME_OBJECT (ogg, "building chain was tracked in existing chains !");
    gst_ogg_chain_free (ogg->building_chain);
    ogg->building_chain = NULL;
  }
  GST_CHAIN_UNLOCK (ogg);
}

/* this function is called when the pad is activated and should start
 * processing data.
 *
 * We check if we can do random access to decide if we work push or
 * pull based.
 */
static gboolean
gst_ogg_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
{
  GstQuery *query;
  gboolean pull_mode;

  query = gst_query_new_scheduling ();

  if (!gst_pad_peer_query (sinkpad, query)) {
    gst_query_unref (query);
    goto activate_push;
  }

  pull_mode = gst_query_has_scheduling_mode_with_flags (query,
      GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
  gst_query_unref (query);

  if (!pull_mode)
    goto activate_push;

  GST_DEBUG_OBJECT (sinkpad, "activating pull");
  return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);

activate_push:
  {
    GST_DEBUG_OBJECT (sinkpad, "activating push");
    return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
  }
}

static gboolean
gst_ogg_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;
  GstOggDemux *ogg;

  ogg = GST_OGG_DEMUX (parent);

  switch (mode) {
    case GST_PAD_MODE_PUSH:
      ogg->pullmode = FALSE;
      ogg->resync = FALSE;
      if (active) {
        ogg->seek_event_thread_stop = FALSE;
        ogg->seek_thread_started = FALSE;
        ogg->seek_event_thread = g_thread_new ("seek_event_thread",
            (GThreadFunc) gst_ogg_demux_loop_push, gst_object_ref (ogg));
        /* And wait for the thread to start.
         * FIXME : This is hackish. And one wonders why we need a separate thread to
         * seek to a certain offset */
        g_mutex_lock (&ogg->seek_event_mutex);
        while (!ogg->seek_thread_started) {
          g_cond_wait (&ogg->thread_started_cond, &ogg->seek_event_mutex);
        }
        g_mutex_unlock (&ogg->seek_event_mutex);
      } else {
        g_mutex_lock (&ogg->seek_event_mutex);
        ogg->seek_event_thread_stop = TRUE;
        g_cond_broadcast (&ogg->seek_event_cond);
        g_mutex_unlock (&ogg->seek_event_mutex);
        g_thread_join (ogg->seek_event_thread);
        ogg->seek_event_thread = NULL;
      }
      res = TRUE;
      break;
    case GST_PAD_MODE_PULL:
      if (active) {
        ogg->need_chains = TRUE;
        ogg->pullmode = TRUE;

        res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ogg_demux_loop,
            sinkpad, NULL);
      } else {
        res = gst_pad_stop_task (sinkpad);
      }
      break;
    default:
      res = FALSE;
      break;
  }
  return res;
}

static GstStateChangeReturn
gst_ogg_demux_change_state (GstElement * element, GstStateChange transition)
{
  GstOggDemux *ogg;
  GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;

  ogg = GST_OGG_DEMUX (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      ogg->basetime = 0;
      ogg_sync_init (&ogg->sync);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      ogg_sync_reset (&ogg->sync);
      ogg->running = FALSE;
      ogg->bitrate = 0;
      ogg->total_time = -1;
      GST_PUSH_LOCK (ogg);
      ogg->push_byte_offset = 0;
      ogg->push_byte_length = -1;
      ogg->push_time_length = GST_CLOCK_TIME_NONE;
      ogg->push_time_offset = GST_CLOCK_TIME_NONE;
      ogg->push_state = PUSH_PLAYING;
      ogg->have_group_id = FALSE;
      ogg->group_id = G_MAXUINT;

      ogg->push_disable_seeking = FALSE;
      gst_ogg_demux_query_duration_push (ogg);
      GST_PUSH_UNLOCK (ogg);
      gst_segment_init (&ogg->segment, GST_FORMAT_TIME);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_ogg_demux_clear_chains (ogg);
      GST_OBJECT_LOCK (ogg);
      ogg->running = FALSE;
      GST_OBJECT_UNLOCK (ogg);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      ogg_sync_clear (&ogg->sync);
      break;
    default:
      break;
  }
  return result;
}

gboolean
gst_ogg_demux_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_ogg_demux_debug, "oggdemux", 0, "ogg demuxer");
  GST_DEBUG_CATEGORY_INIT (gst_ogg_demux_setup_debug, "oggdemux_setup", 0,
      "ogg demuxer setup stage when parsing pipeline");

#ifdef ENABLE_NLS
  GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
      LOCALEDIR);
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif

  return gst_element_register (plugin, "oggdemux", GST_RANK_PRIMARY,
      GST_TYPE_OGG_DEMUX);
}

/* prints all info about the element */
#undef GST_CAT_DEFAULT
#define GST_CAT_DEFAULT gst_ogg_demux_setup_debug

#ifdef GST_DISABLE_GST_DEBUG

static void
gst_ogg_print (GstOggDemux * ogg)
{
  /* NOP */
}

#else /* !GST_DISABLE_GST_DEBUG */

static void
gst_ogg_print (GstOggDemux * ogg)
{
  guint j, i;

  GST_INFO_OBJECT (ogg, "%u chains", ogg->chains->len);
  GST_INFO_OBJECT (ogg, " total time: %" GST_TIME_FORMAT,
      GST_TIME_ARGS (ogg->total_time));

  for (i = 0; i < ogg->chains->len; i++) {
    GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i);

    GST_INFO_OBJECT (ogg, " chain %d (%u streams):", i, chain->streams->len);
    GST_INFO_OBJECT (ogg,
        "  offset: %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT, chain->offset,
        chain->end_offset);
    GST_INFO_OBJECT (ogg, "  begin time: %" GST_TIME_FORMAT,
        GST_TIME_ARGS (chain->begin_time));
    GST_INFO_OBJECT (ogg, "  total time: %" GST_TIME_FORMAT,
        GST_TIME_ARGS (chain->total_time));
    GST_INFO_OBJECT (ogg, "  segment start: %" GST_TIME_FORMAT,
        GST_TIME_ARGS (chain->segment_start));
    GST_INFO_OBJECT (ogg, "  segment stop:  %" GST_TIME_FORMAT,
        GST_TIME_ARGS (chain->segment_stop));

    for (j = 0; j < chain->streams->len; j++) {
      GstOggPad *stream = g_array_index (chain->streams, GstOggPad *, j);

      GST_INFO_OBJECT (ogg, "  stream %08x: %s", stream->map.serialno,
          gst_ogg_stream_get_media_type (&stream->map));
      GST_INFO_OBJECT (ogg, "   start time:       %" GST_TIME_FORMAT,
          GST_TIME_ARGS (stream->start_time));
    }
  }
}
#endif /* GST_DISABLE_GST_DEBUG */
