 /*
  * This library is licensed under 2 different licenses and you
  * can choose to use it under the terms of either one of them. The
  * two licenses are the MPL 1.1 and the LGPL.
  *
  * MPL:
  *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * compliance with the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/.
  *
  * Software distributed under the License is distributed on an "AS IS"
  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  * License for the specific language governing rights and limitations
  * under the License.
  *
  * LGPL:
  *
  * 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.
  *
  * The Original Code is Fluendo MPEG Demuxer plugin.
  *
  * The Initial Developer of the Original Code is Fluendo, S.L.
  * Portions created by Fluendo, S.L. are Copyright (C) 2005
  * Fluendo, S.L. All Rights Reserved.
  *
  * Contributor(s): Wim Taymans <wim@fluendo.com>
  *                 Jan Schmidt <thaytan@noraisin.net>
  */

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

#include <string.h>

#include <gst/tag/tag.h>
#include <gst/pbutils/pbutils.h>

#include "gstmpegdefs.h"
#include "gstmpegdemux.h"

#define BLOCK_SZ                    32768
#define SCAN_SCR_SZ                 12
#define SCAN_PTS_SZ                 80

#define SEGMENT_THRESHOLD (300*GST_MSECOND)
#define VIDEO_SEGMENT_THRESHOLD (500*GST_MSECOND)

#define DURATION_SCAN_LIMIT         4 * 1024 * 1024

typedef enum
{
  SCAN_SCR,
  SCAN_DTS,
  SCAN_PTS
} SCAN_MODE;

/* We clamp scr delta with 0 so negative bytes won't be possible */
#define GSTTIME_TO_BYTES(time) \
  ((time != -1) ? gst_util_uint64_scale (MAX(0,(gint64) (GSTTIME_TO_MPEGTIME(time))), demux->scr_rate_n, demux->scr_rate_d) : -1)
#define BYTES_TO_GSTTIME(bytes) ((bytes != -1) ? MPEGTIME_TO_GSTTIME(gst_util_uint64_scale (bytes, demux->scr_rate_d, demux->scr_rate_n)) : -1)

#define ADAPTER_OFFSET_FLUSH(_bytes_) demux->adapter_offset += (_bytes_)

GST_DEBUG_CATEGORY_STATIC (gstflupsdemux_debug);
#define GST_CAT_DEFAULT (gstflupsdemux_debug)

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

enum
{
  PROP_0,
  /* FILL ME */
};

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/mpeg, "
        "mpegversion = (int) { 1, 2 }, "
        "systemstream = (boolean) TRUE;" "video/x-cdxa")
    );

static GstStaticPadTemplate video_template =
    GST_STATIC_PAD_TEMPLATE ("video_%02x",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("video/mpeg, "
        "mpegversion = (int) { 1, 2, 4 }, " "systemstream = (boolean) FALSE, "
        "parsed = (boolean) FALSE; " "video/x-h264")
    );

static GstStaticPadTemplate audio_template =
    GST_STATIC_PAD_TEMPLATE ("audio_%02x",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) 1;"
        "audio/mpeg, mpegversion = (int) 4, stream-format = (string) { adts, loas };"
        "audio/x-private1-lpcm; "
        "audio/x-private1-ac3;" "audio/x-private1-dts;" "audio/ac3")
    );

static GstStaticPadTemplate subpicture_template =
GST_STATIC_PAD_TEMPLATE ("subpicture_%02x",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("subpicture/x-dvd")
    );

static GstStaticPadTemplate private_template =
GST_STATIC_PAD_TEMPLATE ("private_%d",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static void gst_ps_demux_base_init (GstPsDemuxClass * klass);
static void gst_ps_demux_class_init (GstPsDemuxClass * klass);
static void gst_ps_demux_init (GstPsDemux * demux);
static void gst_ps_demux_finalize (GstPsDemux * demux);
static void gst_ps_demux_reset (GstPsDemux * demux);

static gboolean gst_ps_demux_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstFlowReturn gst_ps_demux_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static gboolean gst_ps_demux_sink_activate (GstPad * sinkpad,
    GstObject * parent);
static gboolean gst_ps_demux_sink_activate_mode (GstPad * pad,
    GstObject * parent, GstPadMode mode, gboolean active);
static void gst_ps_demux_loop (GstPad * pad);

static gboolean gst_ps_demux_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_ps_demux_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);

static GstStateChangeReturn gst_ps_demux_change_state (GstElement * element,
    GstStateChange transition);

static inline gboolean gst_ps_demux_scan_forward_ts (GstPsDemux * demux,
    guint64 * pos, SCAN_MODE mode, guint64 * rts, gint limit);
static inline gboolean gst_ps_demux_scan_backward_ts (GstPsDemux * demux,
    guint64 * pos, SCAN_MODE mode, guint64 * rts, gint limit);

static inline void gst_ps_demux_send_gap_updates (GstPsDemux * demux,
    GstClockTime new_time);
static inline void gst_ps_demux_clear_times (GstPsDemux * demux);

static void gst_ps_demux_reset_psm (GstPsDemux * demux);
static void gst_ps_demux_flush (GstPsDemux * demux);

static GstElementClass *parent_class = NULL;

static void gst_segment_set_position (GstSegment * segment, GstFormat format,
    guint64 position);
static void gst_segment_set_duration (GstSegment * segment, GstFormat format,
    guint64 duration);

/*static guint gst_ps_demux_signals[LAST_SIGNAL] = { 0 };*/

GType
gst_ps_demux_get_type (void)
{
  static GType ps_demux_type = 0;

  if (!ps_demux_type) {
    static const GTypeInfo ps_demux_info = {
      sizeof (GstPsDemuxClass),
      (GBaseInitFunc) gst_ps_demux_base_init,
      NULL,
      (GClassInitFunc) gst_ps_demux_class_init,
      NULL,
      NULL,
      sizeof (GstPsDemux),
      0,
      (GInstanceInitFunc) gst_ps_demux_init,
      NULL
    };

    ps_demux_type =
        g_type_register_static (GST_TYPE_ELEMENT, "GstMpegPSDemux",
        &ps_demux_info, 0);

    GST_DEBUG_CATEGORY_INIT (gstflupsdemux_debug, "mpegpsdemux", 0,
        "MPEG program stream demultiplexer element");
  }

  return ps_demux_type;
}

static void
gst_ps_demux_base_init (GstPsDemuxClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  klass->sink_template = gst_static_pad_template_get (&sink_template);
  klass->video_template = gst_static_pad_template_get (&video_template);
  klass->audio_template = gst_static_pad_template_get (&audio_template);
  klass->subpicture_template =
      gst_static_pad_template_get (&subpicture_template);
  klass->private_template = gst_static_pad_template_get (&private_template);

  gst_element_class_add_pad_template (element_class, klass->video_template);
  gst_element_class_add_pad_template (element_class, klass->audio_template);
  gst_element_class_add_pad_template (element_class,
      klass->subpicture_template);
  gst_element_class_add_pad_template (element_class, klass->private_template);
  gst_element_class_add_pad_template (element_class, klass->sink_template);

  gst_element_class_set_static_metadata (element_class,
      "The Fluendo MPEG Program Stream Demuxer", "Codec/Demuxer",
      "Demultiplexes MPEG Program Streams", "Wim Taymans <wim@fluendo.com>");
}

static void
gst_ps_demux_class_init (GstPsDemuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  gobject_class->finalize = (GObjectFinalizeFunc) gst_ps_demux_finalize;

  gstelement_class->change_state = gst_ps_demux_change_state;
}

static void
gst_ps_demux_init (GstPsDemux * demux)
{
  GstPsDemuxClass *klass = GST_PS_DEMUX_GET_CLASS (demux);

  demux->sinkpad = gst_pad_new_from_template (klass->sink_template, "sink");
  gst_pad_set_event_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ps_demux_sink_event));
  gst_pad_set_chain_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ps_demux_chain));
  gst_pad_set_activate_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ps_demux_sink_activate));
  gst_pad_set_activatemode_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ps_demux_sink_activate_mode));

  gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);

  demux->streams =
      g_malloc0 (sizeof (GstPsStream *) * (GST_PS_DEMUX_MAX_STREAMS));
  demux->streams_found =
      g_malloc0 (sizeof (GstPsStream *) * (GST_PS_DEMUX_MAX_STREAMS));
  demux->found_count = 0;

  demux->adapter = gst_adapter_new ();
  demux->rev_adapter = gst_adapter_new ();
  demux->flowcombiner = gst_flow_combiner_new ();

  gst_ps_demux_reset (demux);
}

static void
gst_ps_demux_finalize (GstPsDemux * demux)
{
  gst_ps_demux_reset (demux);
  g_free (demux->streams);
  g_free (demux->streams_found);

  gst_flow_combiner_free (demux->flowcombiner);
  g_object_unref (demux->adapter);
  g_object_unref (demux->rev_adapter);

  G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (demux));
}

static void
gst_ps_demux_reset (GstPsDemux * demux)
{
  /* Clean up the streams and pads we allocated */
  gint i;

  for (i = 0; i < GST_PS_DEMUX_MAX_STREAMS; i++) {
    GstPsStream *stream = demux->streams[i];

    if (stream != NULL) {
      if (stream->pad && GST_PAD_PARENT (stream->pad)) {
        gst_flow_combiner_remove_pad (demux->flowcombiner, stream->pad);
        gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
      } else {
        gst_object_unref (stream->pad);
      }

      if (stream->pending_tags)
        gst_tag_list_unref (stream->pending_tags);
      g_free (stream);
      demux->streams[i] = NULL;
    }
  }
  memset (demux->streams_found, 0,
      sizeof (GstPsStream *) * (GST_PS_DEMUX_MAX_STREAMS));
  demux->found_count = 0;

  gst_adapter_clear (demux->adapter);
  gst_adapter_clear (demux->rev_adapter);

  demux->adapter_offset = G_MAXUINT64;
  demux->first_scr = G_MAXUINT64;
  demux->last_scr = G_MAXUINT64;
  demux->current_scr = G_MAXUINT64;
  demux->base_time = G_MAXUINT64;
  demux->scr_rate_n = G_MAXUINT64;
  demux->scr_rate_d = G_MAXUINT64;
  demux->first_pts = G_MAXUINT64;
  demux->last_pts = G_MAXUINT64;
  demux->mux_rate = G_MAXUINT64;
  demux->next_pts = G_MAXUINT64;
  demux->next_dts = G_MAXUINT64;
  demux->need_no_more_pads = TRUE;
  demux->adjust_segment = TRUE;
  gst_ps_demux_reset_psm (demux);
  gst_segment_init (&demux->sink_segment, GST_FORMAT_UNDEFINED);
  gst_segment_init (&demux->src_segment, GST_FORMAT_TIME);
  gst_ps_demux_flush (demux);
  demux->have_group_id = FALSE;
  demux->group_id = G_MAXUINT;
}

static GstPsStream *
gst_ps_demux_create_stream (GstPsDemux * demux, gint id, gint stream_type)
{
  GstPsStream *stream;
  GstPadTemplate *template;
  gchar *name;
  GstPsDemuxClass *klass = GST_PS_DEMUX_GET_CLASS (demux);
  GstCaps *caps;
  GstClockTime threshold = SEGMENT_THRESHOLD;
  GstEvent *event;
  gchar *stream_id;

  name = NULL;
  template = NULL;
  caps = NULL;

  GST_DEBUG_OBJECT (demux, "create stream id 0x%02x, type 0x%02x", id,
      stream_type);

  switch (stream_type) {
    case ST_VIDEO_MPEG1:
    case ST_VIDEO_MPEG2:
    case ST_VIDEO_MPEG4:
    case ST_GST_VIDEO_MPEG1_OR_2:
    {
      gint mpeg_version = 1;
      if (stream_type == ST_VIDEO_MPEG2 ||
          (stream_type == ST_GST_VIDEO_MPEG1_OR_2 && demux->is_mpeg2_pack)) {
        mpeg_version = 2;
      }
      if (stream_type == ST_VIDEO_MPEG4) {
        mpeg_version = 4;
      }

      template = klass->video_template;
      name = g_strdup_printf ("video_%02x", id);
      caps = gst_caps_new_simple ("video/mpeg",
          "mpegversion", G_TYPE_INT, mpeg_version,
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          "parsed", G_TYPE_BOOLEAN, FALSE, NULL);
      threshold = VIDEO_SEGMENT_THRESHOLD;
      break;
    }
    case ST_AUDIO_MPEG1:
    case ST_AUDIO_MPEG2:
      template = klass->audio_template;
      name = g_strdup_printf ("audio_%02x", id);
      caps = gst_caps_new_simple ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, NULL);
      break;
    case ST_PRIVATE_SECTIONS:
    case ST_PRIVATE_DATA:
    case ST_MHEG:
    case ST_DSMCC:
      break;
    case ST_AUDIO_AAC_ADTS:
      template = klass->audio_template;
      name = g_strdup_printf ("audio_%02x", id);
      caps = gst_caps_new_simple ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 4,
          "stream-format", G_TYPE_STRING, "adts", NULL);
      break;
    case ST_AUDIO_AAC_LOAS:    // LATM/LOAS AAC syntax
      template = klass->audio_template;
      name = g_strdup_printf ("audio_%02x", id);
      caps = gst_caps_new_simple ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 4,
          "stream-format", G_TYPE_STRING, "loas", NULL);
      break;
    case ST_VIDEO_H264:
      template = klass->video_template;
      name = g_strdup_printf ("video_%02x", id);
      caps = gst_caps_new_empty_simple ("video/x-h264");
      threshold = VIDEO_SEGMENT_THRESHOLD;
      break;
    case ST_PS_AUDIO_AC3:
      template = klass->audio_template;
      name = g_strdup_printf ("audio_%02x", id);
      caps = gst_caps_new_empty_simple ("audio/x-private1-ac3");
      break;
    case ST_PS_AUDIO_DTS:
      template = klass->audio_template;
      name = g_strdup_printf ("audio_%02x", id);
      caps = gst_caps_new_empty_simple ("audio/x-private1-dts");
      break;
    case ST_PS_AUDIO_LPCM:
      template = klass->audio_template;
      name = g_strdup_printf ("audio_%02x", id);
      caps = gst_caps_new_empty_simple ("audio/x-private1-lpcm");
      break;
    case ST_PS_DVD_SUBPICTURE:
      template = klass->subpicture_template;
      name = g_strdup_printf ("subpicture_%02x", id);
      caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
      break;
    case ST_GST_AUDIO_RAWA52:
      template = klass->audio_template;
      name = g_strdup_printf ("audio_%02x", id);
      caps = gst_caps_new_empty_simple ("audio/ac3");
      break;
    default:
      break;
  }

  if (name == NULL || template == NULL || caps == NULL) {
    g_free (name);
    if (caps)
      gst_caps_unref (caps);
    return FALSE;
  }

  stream = g_new0 (GstPsStream, 1);
  stream->id = id;
  stream->discont = TRUE;
  stream->need_segment = TRUE;
  stream->notlinked = FALSE;
  stream->type = stream_type;
  stream->pending_tags = NULL;
  stream->pad = gst_pad_new_from_template (template, name);
  stream->segment_thresh = threshold;
  gst_pad_set_event_function (stream->pad,
      GST_DEBUG_FUNCPTR (gst_ps_demux_src_event));
  gst_pad_set_query_function (stream->pad,
      GST_DEBUG_FUNCPTR (gst_ps_demux_src_query));
  gst_pad_use_fixed_caps (stream->pad);

  /* needed for set_caps to work */
  if (!gst_pad_set_active (stream->pad, TRUE)) {
    GST_WARNING_OBJECT (demux, "Failed to activate pad %" GST_PTR_FORMAT,
        stream->pad);
  }

  stream_id =
      gst_pad_create_stream_id_printf (stream->pad, GST_ELEMENT_CAST (demux),
      "%02x", id);

  event = gst_pad_get_sticky_event (demux->sinkpad, GST_EVENT_STREAM_START, 0);
  if (event) {
    if (gst_event_parse_group_id (event, &demux->group_id))
      demux->have_group_id = TRUE;
    else
      demux->have_group_id = FALSE;
    gst_event_unref (event);
  } else if (!demux->have_group_id) {
    demux->have_group_id = TRUE;
    demux->group_id = gst_util_group_id_next ();
  }
  event = gst_event_new_stream_start (stream_id);
  if (demux->have_group_id)
    gst_event_set_group_id (event, demux->group_id);

  gst_pad_push_event (stream->pad, event);
  g_free (stream_id);

  gst_pad_set_caps (stream->pad, caps);

  if (!stream->pending_tags)
    stream->pending_tags = gst_tag_list_new_empty ();
  gst_pb_utils_add_codec_description_to_tag_list (stream->pending_tags, NULL,
      caps);

  GST_DEBUG_OBJECT (demux, "create pad %s, caps %" GST_PTR_FORMAT, name, caps);
  gst_caps_unref (caps);
  g_free (name);

  return stream;
}

static GstPsStream *
gst_ps_demux_get_stream (GstPsDemux * demux, gint id, gint type)
{
  GstPsStream *stream = demux->streams[id];

  if (stream == NULL) {
    if (!(stream = gst_ps_demux_create_stream (demux, id, type)))
      goto unknown_stream;

    GST_DEBUG_OBJECT (demux, "adding pad for stream id 0x%02x type 0x%02x", id,
        type);

    if (demux->need_no_more_pads) {
      gst_element_add_pad (GST_ELEMENT (demux), stream->pad);
      gst_flow_combiner_add_pad (demux->flowcombiner, stream->pad);
    } else {
      /* only likely to confuse decodebin etc, so discard */
      /* FIXME should perform full switch protocol:
       * add a whole new set of pads, drop old and no-more-pads again */
      GST_DEBUG_OBJECT (demux,
          "but already signalled no-more-pads; not adding");
      gst_object_ref_sink (stream->pad);
    }

    demux->streams[id] = stream;
    demux->streams_found[demux->found_count++] = stream;
  }
  return stream;

  /* ERROR */
unknown_stream:
  {
    GST_DEBUG_OBJECT (demux, "unknown stream id 0x%02x type 0x%02x", id, type);
    return NULL;
  }
}

static GstPsStream *
gst_ps_demux_get_stream_from_pad (GstPsDemux * demux, GstPad * srcpad)
{
  gint i, count;

  count = demux->found_count;
  for (i = 0; i < count; i++) {
    GstPsStream *stream = demux->streams_found[i];

    if (stream && stream->pad == srcpad)
      return stream;
  }

  GST_DEBUG_OBJECT (srcpad, "no stream found for pad!");
  return NULL;
}

static inline void
gst_ps_demux_send_segment (GstPsDemux * demux, GstPsStream * stream,
    GstClockTime pts)
{
  /* discont */
  if (G_UNLIKELY (stream->need_segment)) {
    GstSegment segment;

    GST_DEBUG ("PTS timestamp:%" GST_TIME_FORMAT " base_time %" GST_TIME_FORMAT
        " src_segment.start:%" GST_TIME_FORMAT " .stop:%" GST_TIME_FORMAT,
        GST_TIME_ARGS (pts), GST_TIME_ARGS (demux->base_time),
        GST_TIME_ARGS (demux->src_segment.start),
        GST_TIME_ARGS (demux->src_segment.stop));

    /* adjust segment start if estimating a seek was off quite a bit,
     * make sure to do for all streams though to preserve a/v sync */
    /* FIXME such adjustment tends to be frowned upon */
    if (pts != GST_CLOCK_TIME_NONE && demux->adjust_segment) {
      if (demux->src_segment.rate > 0) {
        if (GST_CLOCK_DIFF (demux->src_segment.start, pts) > GST_SECOND)
          demux->src_segment.start = pts - demux->base_time;
      } else {
        if (GST_CLOCK_DIFF (demux->src_segment.stop, pts) > GST_SECOND)
          demux->src_segment.stop = pts - demux->base_time;
      }
    }
    demux->adjust_segment = FALSE;

    /* we should be in sync with downstream, so start from our segment notion,
     * which also includes proper base_time etc, tweak it a bit and send */
    gst_segment_copy_into (&demux->src_segment, &segment);
    if (GST_CLOCK_TIME_IS_VALID (demux->base_time)) {
      if (GST_CLOCK_TIME_IS_VALID (segment.start))
        segment.start += demux->base_time;
      if (GST_CLOCK_TIME_IS_VALID (segment.stop))
        segment.stop += demux->base_time;
      segment.time = segment.start - demux->base_time;
    }

    GST_INFO_OBJECT (demux, "sending segment event %" GST_SEGMENT_FORMAT
        " to pad %" GST_PTR_FORMAT, &segment, stream->pad);

    gst_pad_push_event (stream->pad, gst_event_new_segment (&segment));

    stream->need_segment = FALSE;
  }

  if (G_UNLIKELY (stream->pending_tags)) {
    GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
        GST_PTR_FORMAT, stream->pending_tags,
        GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
    gst_pad_push_event (stream->pad, gst_event_new_tag (stream->pending_tags));
    stream->pending_tags = NULL;
  }
}

static GstFlowReturn
gst_ps_demux_send_data (GstPsDemux * demux, GstPsStream * stream,
    GstBuffer * buf)
{
  GstFlowReturn result;
  GstClockTime pts = GST_CLOCK_TIME_NONE, dts = GST_CLOCK_TIME_NONE;

  if (stream == NULL)
    goto no_stream;

  /* timestamps */
  if (G_UNLIKELY (demux->next_pts != G_MAXUINT64))
    pts = MPEGTIME_TO_GSTTIME (demux->next_pts);
  if (G_UNLIKELY (demux->next_dts != G_MAXUINT64))
    dts = MPEGTIME_TO_GSTTIME (demux->next_dts);

  gst_ps_demux_send_segment (demux, stream, pts);

  /* OK, sent new segment now prepare the buffer for sending */
  GST_BUFFER_PTS (buf) = pts;
  GST_BUFFER_DTS (buf) = dts;

  /* update position in the segment */
  gst_segment_set_position (&demux->src_segment, GST_FORMAT_TIME,
      MPEGTIME_TO_GSTTIME (demux->current_scr - demux->first_scr));

  GST_LOG_OBJECT (demux, "last stop position is now %" GST_TIME_FORMAT
      " current scr is %" GST_TIME_FORMAT,
      GST_TIME_ARGS (demux->src_segment.position),
      GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->current_scr)));

  if (demux->src_segment.position != GST_CLOCK_TIME_NONE &&
      demux->base_time != GST_CLOCK_TIME_NONE) {
    GstClockTime new_time = demux->base_time + demux->src_segment.position;

    if (stream->last_ts == GST_CLOCK_TIME_NONE || stream->last_ts < new_time) {
      GST_LOG_OBJECT (demux,
          "last_ts update on pad %s to time %" GST_TIME_FORMAT,
          GST_PAD_NAME (stream->pad), GST_TIME_ARGS (new_time));
      stream->last_ts = new_time;
    }

    gst_ps_demux_send_gap_updates (demux, new_time);
  }

  /* Set the buffer discont flag, and clear discont state on the stream */
  if (stream->discont) {
    GST_DEBUG_OBJECT (demux, "discont buffer to pad %" GST_PTR_FORMAT
        " with PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT,
        stream->pad, GST_TIME_ARGS (pts), GST_TIME_ARGS (dts));
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);

    stream->discont = FALSE;
  } else {
    GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
  }

  demux->next_pts = G_MAXUINT64;
  demux->next_dts = G_MAXUINT64;

  GST_LOG_OBJECT (demux, "pushing stream id 0x%02x type 0x%02x, pts time: %"
      GST_TIME_FORMAT ", size %" G_GSIZE_FORMAT,
      stream->id, stream->type, GST_TIME_ARGS (pts), gst_buffer_get_size (buf));
  result = gst_pad_push (stream->pad, buf);
  GST_LOG_OBJECT (demux, "result: %s", gst_flow_get_name (result));

  return result;

  /* ERROR */
no_stream:
  {
    GST_DEBUG_OBJECT (demux, "no stream given");
    gst_buffer_unref (buf);
    return GST_FLOW_OK;
  }
}

static inline void
gst_ps_demux_mark_discont (GstPsDemux * demux, gboolean discont,
    gboolean need_segment)
{
  gint i, count = demux->found_count;

  /* mark discont on all streams */
  for (i = 0; i < count; i++) {
    GstPsStream *stream = demux->streams_found[i];

    if (G_LIKELY (stream)) {
      stream->discont |= discont;
      stream->need_segment |= need_segment;
      demux->adjust_segment |= need_segment;
      GST_DEBUG_OBJECT (demux, "marked stream as discont %d, need_segment %d",
          stream->discont, stream->need_segment);
    }
  }
}

static gboolean
gst_ps_demux_send_event (GstPsDemux * demux, GstEvent * event)
{
  gint i, count = demux->found_count;
  gboolean ret = FALSE;

  for (i = 0; i < count; i++) {
    GstPsStream *stream = demux->streams_found[i];

    if (stream) {
      if (!gst_pad_push_event (stream->pad, gst_event_ref (event))) {
        GST_DEBUG_OBJECT (stream->pad, "%s event was not handled",
            GST_EVENT_TYPE_NAME (event));
      } else {
        /* If at least one push returns TRUE, then we return TRUE. */
        GST_DEBUG_OBJECT (stream->pad, "%s event was handled",
            GST_EVENT_TYPE_NAME (event));
        ret = TRUE;
      }
    }
  }

  gst_event_unref (event);
  return ret;
}

static gboolean
gst_ps_demux_handle_dvd_event (GstPsDemux * demux, GstEvent * event)
{
  const GstStructure *structure = gst_event_get_structure (event);
  const char *type = gst_structure_get_string (structure, "event");
  gint i;
  gchar cur_stream_name[32];
  GstPsStream *temp = NULL;
  const gchar *lang_code;

  if (strcmp (type, "dvd-lang-codes") == 0) {
    GST_DEBUG_OBJECT (demux, "Handling language codes event");

    /* Create a video pad to ensure have it before emit no more pads */
    (void) gst_ps_demux_get_stream (demux, 0xe0, ST_VIDEO_MPEG2);

    /* Read out the languages for audio streams and request each one that 
     * is present */
    for (i = 0; i < MAX_DVD_AUDIO_STREAMS; i++) {
      gint stream_format;
      gint stream_id;

      g_snprintf (cur_stream_name, 32, "audio-%d-format", i);
      if (!gst_structure_get_int (structure, cur_stream_name, &stream_format))
        continue;

      g_snprintf (cur_stream_name, 32, "audio-%d-stream", i);
      if (!gst_structure_get_int (structure, cur_stream_name, &stream_id))
        continue;
      if (stream_id < 0 || stream_id >= MAX_DVD_AUDIO_STREAMS)
        continue;

      switch (stream_format) {
        case 0x0:
          /* AC3 */
          stream_id += 0x80;
          GST_DEBUG_OBJECT (demux,
              "Audio stream %d format %d ID 0x%02x - AC3", i,
              stream_format, stream_id);
          temp = gst_ps_demux_get_stream (demux, stream_id, ST_PS_AUDIO_AC3);
          break;
        case 0x2:
        case 0x3:
          /* MPEG audio without and with extension stream are
           * treated the same */
          stream_id += 0xC0;
          GST_DEBUG_OBJECT (demux,
              "Audio stream %d format %d ID 0x%02x - MPEG audio", i,
              stream_format, stream_id);
          temp = gst_ps_demux_get_stream (demux, stream_id, ST_AUDIO_MPEG1);
          break;
        case 0x4:
          /* LPCM */
          stream_id += 0xA0;
          GST_DEBUG_OBJECT (demux,
              "Audio stream %d format %d ID 0x%02x - DVD LPCM", i,
              stream_format, stream_id);
          temp = gst_ps_demux_get_stream (demux, stream_id, ST_PS_AUDIO_LPCM);
          break;
        case 0x6:
          /* DTS */
          stream_id += 0x88;
          GST_DEBUG_OBJECT (demux,
              "Audio stream %d format %d ID 0x%02x - DTS", i,
              stream_format, stream_id);
          temp = gst_ps_demux_get_stream (demux, stream_id, ST_PS_AUDIO_DTS);
          break;
        case 0x7:
          /* FIXME: What range is SDDS? */
        default:
          GST_WARNING_OBJECT (demux,
              "Unknown audio stream format in language code event: %d",
              stream_format);
          temp = NULL;
          continue;
      }

      if (temp == NULL)
        continue;

      g_snprintf (cur_stream_name, 32, "audio-%d-language", i);
      lang_code = gst_structure_get_string (structure, cur_stream_name);
      if (lang_code) {
        GstTagList *list = temp->pending_tags;

        if (!list)
          list = gst_tag_list_new_empty ();
        gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
            GST_TAG_LANGUAGE_CODE, lang_code, NULL);
        temp->pending_tags = list;
      }
    }

    /* And subtitle streams */
    for (i = 0; i < MAX_DVD_SUBPICTURE_STREAMS; i++) {
      gint stream_id;

      g_snprintf (cur_stream_name, 32, "subpicture-%d-format", i);
      if (!gst_structure_get_int (structure, cur_stream_name, &stream_id))
        continue;

      g_snprintf (cur_stream_name, 32, "subpicture-%d-stream", i);
      if (!gst_structure_get_int (structure, cur_stream_name, &stream_id))
        continue;
      if (stream_id < 0 || stream_id >= MAX_DVD_SUBPICTURE_STREAMS)
        continue;

      GST_DEBUG_OBJECT (demux, "Subpicture stream %d ID 0x%02x", i,
          0x20 + stream_id);

      /* Retrieve the subpicture stream to force pad creation */
      temp = gst_ps_demux_get_stream (demux, 0x20 + stream_id,
          ST_PS_DVD_SUBPICTURE);
      if (temp == NULL)
        continue;

      g_snprintf (cur_stream_name, 32, "subpicture-%d-language", i);
      lang_code = gst_structure_get_string (structure, cur_stream_name);
      if (lang_code) {
        GstTagList *list = temp->pending_tags;

        if (!list)
          list = gst_tag_list_new_empty ();
        gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
            GST_TAG_LANGUAGE_CODE, lang_code, NULL);
        temp->pending_tags = list;
      }
    }

    GST_DEBUG_OBJECT (demux, "Created all pads from Language Codes event, "
        "signalling no-more-pads");

    gst_element_no_more_pads (GST_ELEMENT (demux));
    demux->need_no_more_pads = FALSE;
  } else {
    /* forward to all pads, e.g. dvd clut event */
    gst_event_ref (event);
    gst_ps_demux_send_event (demux, event);
  }

  gst_event_unref (event);
  return TRUE;
}

static void
gst_ps_demux_flush (GstPsDemux * demux)
{
  GST_DEBUG_OBJECT (demux, "flushing demuxer");
  gst_adapter_clear (demux->adapter);
  gst_adapter_clear (demux->rev_adapter);
  gst_pes_filter_drain (&demux->filter);
  gst_ps_demux_clear_times (demux);
  demux->adapter_offset = G_MAXUINT64;
  demux->current_scr = G_MAXUINT64;
  demux->bytes_since_scr = 0;
}

static inline void
gst_ps_demux_clear_times (GstPsDemux * demux)
{
  gint i, count = demux->found_count;

  gst_flow_combiner_reset (demux->flowcombiner);
  /* Clear the last ts for all streams */
  for (i = 0; i < count; i++) {
    GstPsStream *stream = demux->streams_found[i];

    if (G_LIKELY (stream)) {
      stream->last_ts = GST_CLOCK_TIME_NONE;
    }
  }
}

static inline void
gst_ps_demux_send_gap_updates (GstPsDemux * demux, GstClockTime new_start)
{
  GstClockTime base_time, stop;
  gint i, count = demux->found_count;
  GstEvent *event = NULL;

  /* Advance all lagging streams by sending a gap event */
  if ((base_time = demux->base_time) == GST_CLOCK_TIME_NONE)
    base_time = 0;

  stop = demux->src_segment.stop;
  if (stop != GST_CLOCK_TIME_NONE)
    stop += base_time;

  if (new_start > stop)
    return;

  /* FIXME: Handle reverse playback */
  for (i = 0; i < count; i++) {
    GstPsStream *stream = demux->streams_found[i];

    if (stream) {
      if (stream->last_ts == GST_CLOCK_TIME_NONE ||
          stream->last_ts < demux->src_segment.start + base_time)
        stream->last_ts = demux->src_segment.start + base_time;

      if (stream->last_ts + stream->segment_thresh < new_start) {
        /* should send segment info before gap event */
        gst_ps_demux_send_segment (demux, stream, GST_CLOCK_TIME_NONE);

        GST_LOG_OBJECT (demux,
            "Sending gap update to pad %s time %" GST_TIME_FORMAT,
            GST_PAD_NAME (stream->pad), GST_TIME_ARGS (new_start));
        event =
            gst_event_new_gap (stream->last_ts, new_start - stream->last_ts);
        gst_pad_push_event (stream->pad, event);
        stream->last_ts = new_start;
      }
    }
  }
}

static inline gboolean
have_open_streams (GstPsDemux * demux)
{
  return (demux->streams_found[0] != NULL);
}

static gboolean
gst_ps_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  GstPsDemux *demux = GST_PS_DEMUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      gst_ps_demux_send_event (demux, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_ps_demux_send_event (demux, event);
      gst_segment_init (&demux->sink_segment, GST_FORMAT_UNDEFINED);
      gst_ps_demux_flush (demux);
      break;
    case GST_EVENT_SEGMENT:
    {
      const GstSegment *segment;

      gst_event_parse_segment (event, &segment);
      gst_segment_copy_into (segment, &demux->sink_segment);

      GST_INFO_OBJECT (demux, "received segment %" GST_SEGMENT_FORMAT, segment);

      /* we need to emit a new segment */
      gst_ps_demux_mark_discont (demux, TRUE, TRUE);

      if (segment->format == GST_FORMAT_BYTES
          && demux->scr_rate_n != G_MAXUINT64
          && demux->scr_rate_d != G_MAXUINT64) {
        demux->src_segment.rate = segment->rate;
        demux->src_segment.applied_rate = segment->applied_rate;
        demux->src_segment.format = GST_FORMAT_TIME;
        demux->src_segment.start = BYTES_TO_GSTTIME (segment->start);
        demux->src_segment.stop = BYTES_TO_GSTTIME (segment->stop);
        demux->src_segment.time = BYTES_TO_GSTTIME (segment->time);
      } else if (segment->format == GST_FORMAT_TIME) {
        /* we expect our timeline (SCR, PTS) to match the one from upstream,
         * if not, will adjust with offset later on */
        gst_segment_copy_into (segment, &demux->src_segment);
        /* accept upstream segment without adjusting */
        demux->adjust_segment = FALSE;
      }

      gst_event_unref (event);

      break;
    }
    case GST_EVENT_EOS:
      GST_INFO_OBJECT (demux, "Received EOS");
      if (!gst_ps_demux_send_event (demux, event)
          && !have_open_streams (demux)) {
        GST_WARNING_OBJECT (demux, "EOS and no streams open");
        GST_ELEMENT_ERROR (demux, STREAM, FAILED,
            ("Internal data stream error."), ("No valid streams detected"));
      }
      break;
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
    {
      const GstStructure *structure = gst_event_get_structure (event);

      if (structure != NULL
          && gst_structure_has_name (structure, "application/x-gst-dvd")) {
        res = gst_ps_demux_handle_dvd_event (demux, event);
      } else {
        gst_ps_demux_send_event (demux, event);
      }
      break;
    }
    case GST_EVENT_CAPS:
      gst_event_unref (event);
      break;
    default:
      gst_ps_demux_send_event (demux, event);
      break;
  }

  return res;
}

static gboolean
gst_ps_demux_handle_seek_push (GstPsDemux * demux, GstEvent * event)
{
  gboolean res = FALSE;
  gdouble rate;
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  gint64 bstart, bstop;
  GstEvent *bevent;

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

  GST_DEBUG_OBJECT (demux, "seek event, rate: %f start: %" GST_TIME_FORMAT
      " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start),
      GST_TIME_ARGS (stop));

  if (format == GST_FORMAT_BYTES) {
    GST_DEBUG_OBJECT (demux, "seek not supported on format %d", format);
    goto not_supported;
  }

  GST_DEBUG_OBJECT (demux, "seek - trying directly upstream first");

  /* first try original format seek */
  (void) gst_event_ref (event);
  if ((res = gst_pad_push_event (demux->sinkpad, event)))
    goto done;

  if (format != GST_FORMAT_TIME) {
    /* From here down, we only support time based seeks */
    GST_DEBUG_OBJECT (demux, "seek not supported on format %d", format);
    goto not_supported;
  }

  /* We need to convert to byte based seek and we need a scr_rate for that. */
  if (demux->scr_rate_n == G_MAXUINT64 || demux->scr_rate_d == G_MAXUINT64) {
    GST_DEBUG_OBJECT (demux, "seek not possible, no scr_rate");
    goto not_supported;
  }

  GST_DEBUG_OBJECT (demux, "try with scr_rate interpolation");

  bstart = GSTTIME_TO_BYTES ((guint64) start);
  bstop = GSTTIME_TO_BYTES ((guint64) stop);

  GST_DEBUG_OBJECT (demux, "in bytes bstart %" G_GINT64_FORMAT " bstop %"
      G_GINT64_FORMAT, bstart, bstop);
  bevent = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, start_type,
      bstart, stop_type, bstop);

  res = gst_pad_push_event (demux->sinkpad, bevent);

done:
  gst_event_unref (event);
  return res;

not_supported:
  {
    gst_event_unref (event);

    return FALSE;
  }
}

#define MAX_RECURSION_COUNT 100

/* Binary search for requested SCR */
static inline guint64
find_offset (GstPsDemux * demux, guint64 scr,
    guint64 min_scr, guint64 min_scr_offset,
    guint64 max_scr, guint64 max_scr_offset, int recursion_count)
{
  guint64 scr_rate_n = max_scr_offset - min_scr_offset;
  guint64 scr_rate_d = max_scr - min_scr;
  guint64 fscr = scr;
  guint64 offset;

  if (recursion_count > MAX_RECURSION_COUNT) {
    return -1;
  }

  offset = min_scr_offset +
      MIN (gst_util_uint64_scale (scr - min_scr, scr_rate_n,
          scr_rate_d), demux->sink_segment.stop);

  if (!gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr, 0)) {
    gst_ps_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
  }

  if (fscr == scr || fscr == min_scr || fscr == max_scr) {
    return offset;
  }

  if (fscr < scr) {
    return find_offset (demux, scr, fscr, offset, max_scr, max_scr_offset,
        recursion_count + 1);
  } else {
    return find_offset (demux, scr, min_scr, min_scr_offset, fscr, offset,
        recursion_count + 1);
  }
}

static inline gboolean
gst_ps_demux_do_seek (GstPsDemux * demux, GstSegment * seeksegment)
{
  gboolean found;
  guint64 fscr, offset;
  guint64 scr = GSTTIME_TO_MPEGTIME (seeksegment->position + demux->base_time);

  /* In some clips the PTS values are completely unaligned with SCR values.
   * To improve the seek in that situation we apply a factor considering the
   * relationship between last PTS and last SCR */
  if (demux->last_scr > demux->last_pts)
    scr = gst_util_uint64_scale (scr, demux->last_scr, demux->last_pts);

  scr = MIN (demux->last_scr, scr);
  scr = MAX (demux->first_scr, scr);
  fscr = scr;

  GST_INFO_OBJECT (demux, "sink segment configured %" GST_SEGMENT_FORMAT
      ", trying to go at SCR: %" G_GUINT64_FORMAT, &demux->sink_segment, scr);

  offset =
      find_offset (demux, scr, demux->first_scr, demux->first_scr_offset,
      demux->last_scr, demux->last_scr_offset, 0);

  if (offset == (guint64) - 1) {
    return FALSE;
  }

  found = gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
  if (!found)
    found = gst_ps_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr, 0);

  while (found && fscr < scr) {
    offset++;
    found = gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
  }

  while (found && fscr > scr && offset > 0) {
    offset--;
    found = gst_ps_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
  }

  GST_INFO_OBJECT (demux, "doing seek at offset %" G_GUINT64_FORMAT
      " SCR: %" G_GUINT64_FORMAT " %" GST_TIME_FORMAT,
      offset, fscr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (fscr)));

  gst_segment_set_position (&demux->sink_segment, GST_FORMAT_BYTES, offset);

  return TRUE;
}

static gboolean
gst_ps_demux_handle_seek_pull (GstPsDemux * demux, GstEvent * event)
{
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  gdouble rate;
  gboolean update, flush;
  GstSegment seeksegment;
  GstClockTime first_pts = MPEGTIME_TO_GSTTIME (demux->first_pts);

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

  if (format != GST_FORMAT_TIME)
    goto wrong_format;

  GST_DEBUG_OBJECT (demux, "Seek requested start %" GST_TIME_FORMAT " stop %"
      GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop));

  /* We need to convert to byte based seek and we need a scr_rate for that. */
  if (demux->scr_rate_n == G_MAXUINT64 || demux->scr_rate_d == G_MAXUINT64)
    goto no_scr_rate;

  flush = flags & GST_SEEK_FLAG_FLUSH;
  /* keyframe = flags & GST_SEEK_FLAG_KEY_UNIT; *//* FIXME */

  if (flush) {
    /* Flush start up and downstream to make sure data flow and loops are
       idle */
    demux->flushing = TRUE;
    gst_ps_demux_send_event (demux, gst_event_new_flush_start ());
    gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
  } else {
    /* Pause the pulling task */
    gst_pad_pause_task (demux->sinkpad);
  }

  /* Take the stream lock */
  GST_PAD_STREAM_LOCK (demux->sinkpad);

  if (flush) {
    /* Stop flushing upstream we need to pull */
    demux->flushing = FALSE;
    gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop (TRUE));
  }

  /* Work on a copy until we are sure the seek succeeded. */
  memcpy (&seeksegment, &demux->src_segment, sizeof (GstSegment));

  GST_DEBUG_OBJECT (demux, "segment before configure %" GST_SEGMENT_FORMAT,
      &demux->src_segment);

  /* Apply the seek to our segment */
  if (!gst_segment_do_seek (&seeksegment, rate, format, flags,
          start_type, start, stop_type, stop, &update))
    goto seek_error;

  GST_DEBUG_OBJECT (demux, "seek segment configured %" GST_SEGMENT_FORMAT,
      &seeksegment);

  if (flush || seeksegment.position != demux->src_segment.position) {
    /* Do the actual seeking */
    if (!gst_ps_demux_do_seek (demux, &seeksegment)) {
      return FALSE;
    }
  }

  /* check the limits */
  if (seeksegment.rate > 0.0) {
    if (seeksegment.start < first_pts - demux->base_time) {
      seeksegment.start = first_pts - demux->base_time;
      seeksegment.position = seeksegment.start;
    }
  }

  /* update the rate in our src segment */
  demux->sink_segment.rate = rate;

  GST_DEBUG_OBJECT (demux, "seek segment adjusted %" GST_SEGMENT_FORMAT,
      &seeksegment);

  if (flush) {
    /* Stop flushing, the sinks are at time 0 now */
    gst_ps_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
  }

  if (flush || seeksegment.position != demux->src_segment.position) {
    gst_ps_demux_flush (demux);
  }

  /* Ok seek succeeded, take the newly configured segment */
  memcpy (&demux->src_segment, &seeksegment, sizeof (GstSegment));

  /* Notify about the start of a new segment */
  if (demux->src_segment.flags & GST_SEEK_FLAG_SEGMENT) {
    gst_element_post_message (GST_ELEMENT (demux),
        gst_message_new_segment_start (GST_OBJECT (demux),
            demux->src_segment.format, demux->src_segment.position));
  }

  /* Tell all the stream a new segment is needed */
  gst_ps_demux_mark_discont (demux, TRUE, TRUE);

  gst_pad_start_task (demux->sinkpad,
      (GstTaskFunction) gst_ps_demux_loop, demux->sinkpad, NULL);

  GST_PAD_STREAM_UNLOCK (demux->sinkpad);

  gst_event_unref (event);
  return TRUE;

  /* ERRORS */
wrong_format:
  {
    GST_WARNING_OBJECT (demux, "we only support seeking in TIME or BYTES "
        "formats");
    gst_event_unref (event);
    return FALSE;
  }
no_scr_rate:
  {
    GST_WARNING_OBJECT (demux, "seek not possible, no scr_rate");
    gst_event_unref (event);
    return FALSE;
  }
seek_error:
  {
    GST_WARNING_OBJECT (demux, "couldn't perform seek");
    gst_event_unref (event);
    return FALSE;
  }
}

static gboolean
gst_ps_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = FALSE;
  GstPsDemux *demux = GST_PS_DEMUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      if (demux->random_access) {
        res = gst_ps_demux_handle_seek_pull (demux, event);
      } else {
        res = gst_ps_demux_handle_seek_push (demux, event);
      }
      break;
    case GST_EVENT_RECONFIGURE:{
      GstPsStream *stream;

      stream = gst_ps_demux_get_stream_from_pad (demux, pad);
      if (stream != NULL)
        stream->notlinked = FALSE;

      gst_event_unref (event);
      res = TRUE;
      break;
    }
    default:
      res = gst_pad_push_event (demux->sinkpad, event);
      break;
  }

  return res;
}

static gboolean
gst_ps_demux_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res = FALSE;
  GstPsDemux *demux = GST_PS_DEMUX (parent);

  GST_LOG_OBJECT (demux, "Have query of type %d on pad %" GST_PTR_FORMAT,
      GST_QUERY_TYPE (query), pad);

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

      /* See if upstream can immediately answer */
      res = gst_pad_peer_query (demux->sinkpad, query);
      if (res)
        break;

      gst_query_parse_position (query, &format, NULL);

      if (format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (demux, "position not supported for format: %s",
            gst_format_get_name (format));
        goto not_supported;
      }

      pos = demux->src_segment.position - demux->src_segment.start;
      GST_LOG_OBJECT (demux, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS (pos));

      gst_query_set_position (query, format, pos);
      res = TRUE;
      break;
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;
      gint64 duration;
      GstQuery *byte_query;

      gst_query_parse_duration (query, &format, NULL);

      if (G_LIKELY (format == GST_FORMAT_TIME &&
              GST_CLOCK_TIME_IS_VALID (demux->src_segment.duration))) {
        gst_query_set_duration (query, GST_FORMAT_TIME,
            demux->src_segment.duration);
        res = TRUE;
        break;
      }

      /* For any format other than bytes, see if upstream knows first */
      if (format == GST_FORMAT_BYTES) {
        GST_DEBUG_OBJECT (demux, "duration not supported for format: %s",
            gst_format_get_name (format));
        goto not_supported;
      }

      if (gst_pad_peer_query (demux->sinkpad, query)) {
        res = TRUE;
        break;
      }

      /* Upstream didn't know, so we can only answer TIME queries from
       * here on */
      if (format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (demux, "duration not supported for format: %s",
            gst_format_get_name (format));
        goto not_supported;
      }

      if (demux->mux_rate == -1) {
        GST_DEBUG_OBJECT (demux, "duration not possible, no mux_rate");
        goto not_supported;
      }

      byte_query = gst_query_new_duration (GST_FORMAT_BYTES);

      if (!gst_pad_peer_query (demux->sinkpad, byte_query)) {
        GST_LOG_OBJECT (demux, "query on peer pad failed");
        gst_query_unref (byte_query);
        goto not_supported;
      }

      gst_query_parse_duration (byte_query, &format, &duration);
      gst_query_unref (byte_query);

      GST_LOG_OBJECT (demux,
          "query on peer pad reported bytes %" G_GUINT64_FORMAT, duration);

      duration = BYTES_TO_GSTTIME ((guint64) duration);

      GST_LOG_OBJECT (demux, "converted to time %" GST_TIME_FORMAT,
          GST_TIME_ARGS (duration));

      gst_query_set_duration (query, GST_FORMAT_TIME, duration);
      res = TRUE;
      break;
    }
    case GST_QUERY_SEEKING:{
      GstFormat fmt;

      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);

      res = TRUE;
      if (demux->random_access) {
        /* In pull mode we can seek in TIME format if we have the SCR */
        if (fmt != GST_FORMAT_TIME || demux->scr_rate_n == G_MAXUINT64
            || demux->scr_rate_d == G_MAXUINT64)
          gst_query_set_seeking (query, fmt, FALSE, -1, -1);
        else
          gst_query_set_seeking (query, fmt, TRUE, 0, -1);
      } else {
        if (fmt == GST_FORMAT_BYTES) {
          /* Seeking in BYTES format not supported at all */
          gst_query_set_seeking (query, fmt, FALSE, -1, -1);
        } else {
          GstQuery *peerquery;
          gboolean seekable;

          /* Then ask upstream */
          res = gst_pad_peer_query (demux->sinkpad, query);
          if (res) {
            /* If upstream can handle seeks we're done, if it
             * can't we still have our TIME->BYTES conversion seek
             */
            gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
            if (seekable || fmt != GST_FORMAT_TIME)
              goto beach;
          }

          /* We can seek if upstream supports BYTES seeks and we
           * have the SCR
           */
          peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
          res = gst_pad_peer_query (demux->sinkpad, peerquery);
          if (!res || demux->scr_rate_n == G_MAXUINT64
              || demux->scr_rate_d == G_MAXUINT64) {
            gst_query_set_seeking (query, fmt, FALSE, -1, -1);
          } else {
            gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);
            if (seekable)
              gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
            else
              gst_query_set_seeking (query, fmt, FALSE, -1, -1);
          }

          gst_query_unref (peerquery);
          res = TRUE;
        }
      }
      break;
    }
    case GST_QUERY_SEGMENT:{
      GstFormat format;
      gint64 start, stop;

      format = demux->src_segment.format;

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

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

beach:
  return res;
not_supported:
  return FALSE;
}

static void
gst_ps_demux_reset_psm (GstPsDemux * demux)
{
  gint i;

#define FILL_TYPE(start, stop, type)	\
  for (i=start; i <= stop; i++)			\
    demux->psm[i] = type;

  /* Initialize all fields to -1 first */
  FILL_TYPE (0x00, GST_PS_DEMUX_MAX_PSM - 1, -1);

  FILL_TYPE (0x20, 0x3f, ST_PS_DVD_SUBPICTURE);

  FILL_TYPE (0x80, 0x87, ST_PS_AUDIO_AC3);
  FILL_TYPE (0x88, 0x9f, ST_PS_AUDIO_DTS);
  FILL_TYPE (0xa0, 0xaf, ST_PS_AUDIO_LPCM);

  FILL_TYPE (0xc0, 0xdf, ST_AUDIO_MPEG1);
  FILL_TYPE (0xe0, 0xef, ST_GST_VIDEO_MPEG1_OR_2);

#undef FILL_TYPE
}

/* ISO/IEC 13818-1:
 * pack_header() {
 *     pack_start_code                                   32  bslbf  -+
 *     '01'                                               2  bslbf   |
 *     system_clock_reference_base [32..30]               3  bslbf   |
 *     marker_bit                                         1  bslbf   |
 *     system_clock_reference_base [29..15]              15  bslbf   |
 *     marker_bit                                         1  bslbf   |
 *     system_clock_reference_base [14..0]               15  bslbf   |
 *     marker_bit                                         1  bslbf   | 112 bits
 *     system_clock_reference_extension                   9  ubslbf  |
 *     marker_bit                                         1  bslbf   |
 *     program_mux_rate                                  22  ubslbf  |
 *     marker_bit                                         1  bslbf   |
 *     marker_bit                                         1  bslbf   |
 *     reserved                                           5  bslbf   |
 *     pack_stuffing_length                               3  ubslbf -+
 *
 *     for (i = 0; i < pack_stuffing_length; i++) {
 *         stuffing_byte '1111 1111'                      8  bslbf
 *     }
 *
 * 112 bits = 14 bytes, as max value for pack_stuffing_length is 7, then
 * in total it's needed 14 + 7 = 21 bytes.
 */
#define PACK_START_SIZE     21

static GstFlowReturn
gst_ps_demux_parse_pack_start (GstPsDemux * demux)
{
  const guint8 *data;
  guint length;
  guint32 scr1, scr2;
  guint64 scr, scr_adjusted, new_rate;
  guint64 scr_rate_n;
  guint64 scr_rate_d;
  guint avail = gst_adapter_available (demux->adapter);

  GST_LOG ("parsing pack start");

  if (G_UNLIKELY (avail < PACK_START_SIZE))
    goto need_more_data;

  data = gst_adapter_map (demux->adapter, PACK_START_SIZE);

  /* skip start code */
  data += 4;

  scr1 = GST_READ_UINT32_BE (data);
  scr2 = GST_READ_UINT32_BE (data + 4);

  /* fixed length to begin with, start code and two scr values */
  length = 8 + 4;

  /* start parsing the stream */
  if ((*data & 0xc0) == 0x40) {
    guint32 scr_ext;
    guint32 next32;
    guint8 stuffing_bytes;

    GST_LOG ("Found MPEG2 stream");
    demux->is_mpeg2_pack = TRUE;

    /* mpeg2 has more data */
    length += 2;

    /* :2=01 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 */

    /* check markers */
    if (G_UNLIKELY ((scr1 & 0xc4000400) != 0x44000400))
      goto lost_sync;

    scr = ((guint64) scr1 & 0x38000000) << 3;
    scr |= ((guint64) scr1 & 0x03fff800) << 4;
    scr |= ((guint64) scr1 & 0x000003ff) << 5;
    scr |= ((guint64) scr2 & 0xf8000000) >> 27;

    /* marker:1==1 ! scr_ext:9 ! marker:1==1 */
    if (G_UNLIKELY ((scr2 & 0x04010000) != 0x04010000))
      goto lost_sync;

    scr_ext = (scr2 & 0x03fe0000) >> 17;
    /* We keep the offset of this scr */
    demux->cur_scr_offset = demux->adapter_offset + 12;

    GST_LOG_OBJECT (demux, "SCR: 0x%08" G_GINT64_MODIFIER "x SCRE: 0x%08x",
        scr, scr_ext);

    if (scr_ext) {
      scr = (scr * 300 + scr_ext % 300) / 300;
    }
    /* SCR has been converted into units of 90Khz ticks to make it comparable
       to DTS/PTS, that also implies 1 tick rounding error */
    data += 6;
    /* PMR:22 ! :2==11 ! reserved:5 ! stuffing_len:3 */
    next32 = GST_READ_UINT32_BE (data);
    if (G_UNLIKELY ((next32 & 0x00000300) != 0x00000300))
      goto lost_sync;

    new_rate = (next32 & 0xfffffc00) >> 10;

    stuffing_bytes = (next32 & 0x07);
    GST_LOG_OBJECT (demux, "stuffing bytes: %d", stuffing_bytes);

    data += 4;
    length += stuffing_bytes;
    while (stuffing_bytes--) {
      if (*data++ != 0xff)
        goto lost_sync;
    }
  } else {
    GST_DEBUG ("Found MPEG1 stream");
    demux->is_mpeg2_pack = FALSE;

    /* check markers */
    if (G_UNLIKELY ((scr1 & 0xf1000100) != 0x21000100))
      goto lost_sync;

    if (G_UNLIKELY ((scr2 & 0x01800001) != 0x01800001))
      goto lost_sync;

    /* :4=0010 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 ! marker:1==1 */
    scr = ((guint64) scr1 & 0x0e000000) << 5;
    scr |= ((guint64) scr1 & 0x00fffe00) << 6;
    scr |= ((guint64) scr1 & 0x000000ff) << 7;
    scr |= ((guint64) scr2 & 0xfe000000) >> 25;

    /* We keep the offset of this scr */
    demux->cur_scr_offset = demux->adapter_offset + 8;

    /* marker:1==1 ! mux_rate:22 ! marker:1==1 */
    new_rate = (scr2 & 0x007ffffe) >> 1;

    data += 8;
  }
  new_rate *= MPEG_MUX_RATE_MULT;

  /* scr adjusted is the new scr found + the colected adjustment */
  scr_adjusted = scr + demux->scr_adjust;

  GST_LOG_OBJECT (demux,
      "SCR: %" G_GINT64_FORMAT " (%" G_GINT64_FORMAT "), mux_rate %"
      G_GINT64_FORMAT ", GStreamer Time:%" GST_TIME_FORMAT,
      scr, scr_adjusted, new_rate,
      GST_TIME_ARGS (MPEGTIME_TO_GSTTIME ((guint64) scr)));

  /* keep the first src in order to calculate delta time */
  if (G_UNLIKELY (demux->first_scr == G_MAXUINT64)) {
    gint64 diff;

    demux->first_scr = scr;
    demux->first_scr_offset = demux->cur_scr_offset;
    demux->base_time = MPEGTIME_TO_GSTTIME (demux->first_scr);
    GST_DEBUG_OBJECT (demux, "determined base_time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (demux->base_time));
    /* at begin consider the new_rate as the scr rate, bytes/clock ticks */
    scr_rate_n = new_rate;
    scr_rate_d = CLOCK_FREQ;
    /* our SCR timeline might have offset wrt upstream timeline */
    if (demux->sink_segment.format == GST_FORMAT_TIME) {
      if (demux->sink_segment.start > demux->base_time)
        diff = -(demux->sink_segment.start - demux->base_time);
      else
        diff = demux->base_time - demux->sink_segment.start;
      if (diff > GST_SECOND) {
        GST_DEBUG_OBJECT (demux, "diff of %" GST_TIME_FORMAT
            " wrt upstream start %" GST_TIME_FORMAT "; adjusting base",
            GST_TIME_ARGS (diff), GST_TIME_ARGS (demux->sink_segment.start));
        demux->base_time += diff;
      }
    }
  } else if (G_LIKELY (demux->first_scr_offset != demux->cur_scr_offset)) {
    /* estimate byte rate related to the SCR */
    scr_rate_n = demux->cur_scr_offset - demux->first_scr_offset;
    scr_rate_d = scr_adjusted - demux->first_scr;
  } else {
    scr_rate_n = demux->scr_rate_n;
    scr_rate_d = demux->scr_rate_d;
  }

  GST_LOG_OBJECT (demux, "%s mode scr: %" G_GUINT64_FORMAT " at %"
      G_GUINT64_FORMAT ", first scr: %" G_GUINT64_FORMAT
      " at %" G_GUINT64_FORMAT ", scr rate: %" G_GUINT64_FORMAT
      "/%" G_GUINT64_FORMAT "(%f)",
      ((demux->sink_segment.rate >= 0.0) ? "forward" : "backward"),
      scr, demux->cur_scr_offset,
      demux->first_scr, demux->first_scr_offset,
      scr_rate_n, scr_rate_d, (float) scr_rate_n / scr_rate_d);

  /* adjustment of the SCR */
  if (G_LIKELY (demux->current_scr != G_MAXUINT64)) {
    guint64 diff;
    guint64 old_scr, old_mux_rate, bss, adjust = 0;

    /* keep SCR of the previous packet */
    old_scr = demux->current_scr;
    old_mux_rate = demux->mux_rate;

    /* Bytes since SCR is the amount we placed in the adapter since then
     * (demux->bytes_since_scr) minus the amount remaining in the adapter,
     * clamped to >= 0 */
    bss = MAX (0, (gint) (demux->bytes_since_scr - avail));

    /* estimate the new SCR using the previous one according the notes
       on point 2.5.2.2 of the ISO/IEC 13818-1 document */
    if (old_mux_rate != 0)
      adjust = (bss * CLOCK_FREQ) / old_mux_rate;

    if (demux->sink_segment.rate >= 0.0)
      demux->next_scr = old_scr + adjust;
    else
      demux->next_scr = old_scr - adjust;

    GST_LOG_OBJECT (demux,
        "bss: %" G_GUINT64_FORMAT ", next_scr: %" G_GUINT64_FORMAT
        ", old_scr: %" G_GUINT64_FORMAT ", scr: %" G_GUINT64_FORMAT,
        bss, demux->next_scr, old_scr, scr_adjusted);

    /* calculate the absolute deference between the last scr and
       the new one */
    if (G_UNLIKELY (old_scr > scr_adjusted))
      diff = old_scr - scr_adjusted;
    else
      diff = scr_adjusted - old_scr;

    /* if the difference is more than 1 second we need to reconfigure
       adjustment */
    if (G_UNLIKELY (diff > CLOCK_FREQ)) {
      demux->scr_adjust = demux->next_scr - scr;
      GST_LOG_OBJECT (demux, "discont found, diff: %" G_GINT64_FORMAT
          ", adjust %" G_GINT64_FORMAT, diff, demux->scr_adjust);
      scr_adjusted = demux->next_scr;
      /* don't update rate estimation on disconts */
      scr_rate_n = demux->scr_rate_n;
      scr_rate_d = demux->scr_rate_d;
    } else {
      demux->next_scr = scr_adjusted;
    }
  }

  /* update the current_scr and rate members */
  demux->mux_rate = new_rate;
  demux->current_scr = scr_adjusted;
  demux->scr_rate_n = scr_rate_n;
  demux->scr_rate_d = scr_rate_d;

  /* Reset the bytes_since_scr value to count the data remaining in the
   * adapter */
  demux->bytes_since_scr = avail;

  gst_adapter_unmap (demux->adapter);
  gst_adapter_flush (demux->adapter, length);
  ADAPTER_OFFSET_FLUSH (length);
  return GST_FLOW_OK;

lost_sync:
  {
    GST_DEBUG_OBJECT (demux, "lost sync");
    gst_adapter_unmap (demux->adapter);
    return GST_FLOW_LOST_SYNC;
  }
need_more_data:
  {
    GST_DEBUG_OBJECT (demux, "need more data");
    return GST_FLOW_NEED_MORE_DATA;
  }
}

/* ISO/IEC 13818-1:
 * system_header () {
 *     system_header_start_code                          32  bslbf  -+
 *     header_length                                     16  uimsbf  |
 *     marker_bit                                         1  bslbf   |
 *     rate_bound                                        22  uimsbf  |
 *     marker_bit                                         1  bslbf   |
 *     audio_bound                                        6  uimsbf  |
 *     fixed_flag                                         1  bslbf   |
 *     CSPS_flag                                          1  bslbf   | 96 bits
 *     system_audio_lock_flag                             1  bslbf   |
 *     system_video_lock_flag                             1  bslbf   |
 *     marker_bit                                         1  bslbf   |
 *     video_bound                                        5  uimsbf  |
 *     packet_rate_restriction_flag                       1  bslbf   |
 *     reserved_bits                                      7  bslbf  -+
 *     while (nextbits () = = '1') {
 *         stream_id                                      8  uimsbf -+
 *         '11'                                           2  bslbf   | 24 bits
 *         P-STD_buffer_bound_scale                       1  bslbf   |
 *         P-STD_buffer_size_bound                       13  uimsbf -+
 *     }
 * }
 * 96 bits = 12 bytes, 24 bits = 3 bytes.
 */

static GstFlowReturn
gst_ps_demux_parse_sys_head (GstPsDemux * demux)
{
  guint16 length;
  const guint8 *data;
#ifndef GST_DISABLE_GST_DEBUG
  gboolean csps;
#endif

  if (gst_adapter_available (demux->adapter) < 6)
    goto need_more_data;

  /* start code + length */
  data = gst_adapter_map (demux->adapter, 6);

  /* skip start code */
  data += 4;

  length = GST_READ_UINT16_BE (data);
  GST_DEBUG_OBJECT (demux, "length %d", length);

  length += 6;

  gst_adapter_unmap (demux->adapter);
  if (gst_adapter_available (demux->adapter) < length)
    goto need_more_data;

  data = gst_adapter_map (demux->adapter, length);

  /* skip start code and length */
  data += 6;

  /* marker:1==1 ! rate_bound:22 | marker:1==1 */
  if ((*data & 0x80) != 0x80)
    goto marker_expected;

  {
    guint32 rate_bound;

    if ((data[2] & 0x01) != 0x01)
      goto marker_expected;

    rate_bound = ((guint32) data[0] & 0x7f) << 15;
    rate_bound |= ((guint32) data[1]) << 7;
    rate_bound |= ((guint32) data[2] & 0xfe) >> 1;
    rate_bound *= MPEG_MUX_RATE_MULT;

    GST_DEBUG_OBJECT (demux, "rate bound %u", rate_bound);

    data += 3;
  }

  /* audio_bound:6==1 ! fixed:1 | constrained:1 */
  {
#ifndef GST_DISABLE_GST_DEBUG
    guint8 audio_bound;
    gboolean fixed;

    /* max number of simultaneous audio streams active */
    audio_bound = (data[0] & 0xfc) >> 2;
    /* fixed or variable bitrate */
    fixed = (data[0] & 0x02) == 0x02;
    /* meeting constraints */
    csps = (data[0] & 0x01) == 0x01;

    GST_DEBUG_OBJECT (demux, "audio_bound %d, fixed %d, constrained %d",
        audio_bound, fixed, csps);
#endif
    data += 1;
  }

  /* audio_lock:1 | video_lock:1 | marker:1==1 | video_bound:5 */
  {
#ifndef GST_DISABLE_GST_DEBUG
    gboolean audio_lock;
    gboolean video_lock;
    guint8 video_bound;

    audio_lock = (data[0] & 0x80) == 0x80;
    video_lock = (data[0] & 0x40) == 0x40;
#endif

    if ((data[0] & 0x20) != 0x20)
      goto marker_expected;

#ifndef GST_DISABLE_GST_DEBUG
    /* max number of simultaneous video streams active */
    video_bound = (data[0] & 0x1f);

    GST_DEBUG_OBJECT (demux, "audio_lock %d, video_lock %d, video_bound %d",
        audio_lock, video_lock, video_bound);
#endif
    data += 1;
  }

  /* packet_rate_restriction:1 | reserved:7==0x7F */
  {
#ifndef GST_DISABLE_GST_DEBUG
    gboolean packet_rate_restriction;
#endif
    if ((data[0] & 0x7f) != 0x7f)
      goto marker_expected;
#ifndef GST_DISABLE_GST_DEBUG
    /* only valid if csps is set */
    if (csps) {
      packet_rate_restriction = (data[0] & 0x80) == 0x80;

      GST_DEBUG_OBJECT (demux, "packet_rate_restriction %d",
          packet_rate_restriction);
    }
#endif
  }
  data += 1;

  {
    gint stream_count = (length - 12) / 3;
    gint i;

    GST_DEBUG_OBJECT (demux, "number of streams: %d ", stream_count);

    for (i = 0; i < stream_count; i++) {
      guint8 stream_id;
#ifndef GST_DISABLE_GST_DEBUG
      gboolean STD_buffer_bound_scale;
      guint16 STD_buffer_size_bound;
      guint32 buf_byte_size_bound;
#endif
      stream_id = *data++;
      if (!(stream_id & 0x80))
        goto sys_len_error;

      /* check marker bits */
      if ((*data & 0xC0) != 0xC0)
        goto no_placeholder_bits;
#ifndef GST_DISABLE_GST_DEBUG
      STD_buffer_bound_scale = *data & 0x20;
      STD_buffer_size_bound = ((guint16) (*data++ & 0x1F)) << 8;
      STD_buffer_size_bound |= *data++;

      if (STD_buffer_bound_scale == 0) {
        buf_byte_size_bound = STD_buffer_size_bound * 128;
      } else {
        buf_byte_size_bound = STD_buffer_size_bound * 1024;
      }

      GST_DEBUG_OBJECT (demux, "STD_buffer_bound_scale %d",
          STD_buffer_bound_scale);
      GST_DEBUG_OBJECT (demux, "STD_buffer_size_bound %d or %d bytes",
          STD_buffer_size_bound, buf_byte_size_bound);
#endif
    }
  }

  gst_adapter_unmap (demux->adapter);
  gst_adapter_flush (demux->adapter, length);
  ADAPTER_OFFSET_FLUSH (length);
  return GST_FLOW_OK;

  /* ERRORS */
marker_expected:
  {
    GST_DEBUG_OBJECT (demux, "expecting marker");
    gst_adapter_unmap (demux->adapter);
    return GST_FLOW_LOST_SYNC;
  }
no_placeholder_bits:
  {
    GST_DEBUG_OBJECT (demux, "expecting placeholder bit values"
        " '11' after stream id");
    gst_adapter_unmap (demux->adapter);
    return GST_FLOW_LOST_SYNC;
  }
sys_len_error:
  {
    GST_DEBUG_OBJECT (demux, "error in system header length");
    gst_adapter_unmap (demux->adapter);
    return GST_FLOW_LOST_SYNC;
  }
need_more_data:
  {
    GST_DEBUG_OBJECT (demux, "need more data");
    gst_adapter_unmap (demux->adapter);
    return GST_FLOW_NEED_MORE_DATA;
  }
}

static GstFlowReturn
gst_ps_demux_parse_psm (GstPsDemux * demux)
{
  guint16 length = 0, info_length = 0, es_map_length = 0;
  guint8 psm_version = 0;
  const guint8 *data, *es_map_base;
#ifndef GST_DISABLE_GST_DEBUG
  gboolean applicable;
#endif

  if (gst_adapter_available (demux->adapter) < 6)
    goto need_more_data;

  /* start code + length */
  data = gst_adapter_map (demux->adapter, 6);

  /* skip start code */
  data += 4;

  length = GST_READ_UINT16_BE (data);
  GST_DEBUG_OBJECT (demux, "length %u", length);

  if (G_UNLIKELY (length > 0x3FA))
    goto psm_len_error;

  length += 6;

  gst_adapter_unmap (demux->adapter);

  if (gst_adapter_available (demux->adapter) < length)
    goto need_more_data;

  data = gst_adapter_map (demux->adapter, length);

  /* skip start code and length */
  data += 6;

  /* Read PSM applicable bit together with version */
  psm_version = GST_READ_UINT8 (data);
#ifndef GST_DISABLE_GST_DEBUG
  applicable = (psm_version & 0x80) >> 7;
#endif
  psm_version &= 0x1F;
  GST_DEBUG_OBJECT (demux, "PSM version %u (applicable now %u)", psm_version,
      applicable);

  /* Jump over version and marker bit */
  data += 2;

  /* Read PS info length */
  info_length = GST_READ_UINT16_BE (data);
  /* Cap it to PSM length - needed bytes for ES map length and CRC */
  info_length = MIN (length - 16, info_length);
  GST_DEBUG_OBJECT (demux, "PS info length %u bytes", info_length);

  /* Jump over that section */
  data += (2 + info_length);

  /* Read ES map length */
  es_map_length = GST_READ_UINT16_BE (data);
  /* Cap it to PSM remaining length -  CRC */
  es_map_length = MIN (length - (16 + info_length), es_map_length);
  GST_DEBUG_OBJECT (demux, "ES map length %u bytes", es_map_length);

  /* Jump over the size */
  data += 2;

  /* Now read the ES map */
  es_map_base = data;
  while (es_map_base + 4 <= data + es_map_length) {
    guint8 stream_type = 0, stream_id = 0;
    guint16 stream_info_length = 0;

    stream_type = GST_READ_UINT8 (es_map_base);
    es_map_base++;
    stream_id = GST_READ_UINT8 (es_map_base);
    es_map_base++;
    stream_info_length = GST_READ_UINT16_BE (es_map_base);
    es_map_base += 2;
    /* Cap stream_info_length */
    stream_info_length = MIN (data + es_map_length - es_map_base,
        stream_info_length);

    GST_DEBUG_OBJECT (demux, "Stream type %02X with id %02X and %u bytes info",
        stream_type, stream_id, stream_info_length);
    if (G_LIKELY (stream_id != 0xbd))
      demux->psm[stream_id] = stream_type;
    else {
      /* Ignore stream type for private_stream_1 and discover it looking at
       * the stream data.
       * Fixes demuxing some clips with lpcm that was wrongly declared as
       * mpeg audio */
      GST_DEBUG_OBJECT (demux, "stream type for private_stream_1 ignored");
    }
    es_map_base += stream_info_length;
  }

  gst_adapter_unmap (demux->adapter);
  gst_adapter_flush (demux->adapter, length);
  ADAPTER_OFFSET_FLUSH (length);
  return GST_FLOW_OK;

psm_len_error:
  {
    GST_DEBUG_OBJECT (demux, "error in PSM length");
    gst_adapter_unmap (demux->adapter);
    return GST_FLOW_LOST_SYNC;
  }
need_more_data:
  {
    GST_DEBUG_OBJECT (demux, "need more data");
    return GST_FLOW_NEED_MORE_DATA;
  }
}

static void
gst_ps_demux_resync_cb (GstPESFilter * filter, GstPsDemux * demux)
{
}

static GstFlowReturn
gst_ps_demux_data_cb (GstPESFilter * filter, gboolean first,
    GstBuffer * buffer, GstPsDemux * demux)
{
  GstBuffer *out_buf;
  GstFlowReturn ret = GST_FLOW_OK;
  gint stream_type;
  guint32 start_code;
  guint8 id;
  GstMapInfo map;
  gsize datalen;
  guint offset = 0;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  datalen = map.size;

  start_code = filter->start_code;
  id = filter->id;

  if (first) {
    /* find the stream type */
    stream_type = demux->psm[id];
    if (stream_type == -1) {
      /* no stream type, if PS1, get the new id */
      if (start_code == ID_PRIVATE_STREAM_1 && datalen >= 2) {
        /* VDR writes A52 streams without any header bytes
         * (see ftp://ftp.mplayerhq.hu/MPlayer/samples/MPEG-VOB/vdr-AC3) */
        if (datalen >= 4) {
          guint hdr = GST_READ_UINT32_BE (map.data);

          if (G_UNLIKELY ((hdr & 0xffff0000) == AC3_SYNC_WORD)) {
            id = 0x80;
            stream_type = demux->psm[id] = ST_GST_AUDIO_RAWA52;
            GST_DEBUG_OBJECT (demux, "Found VDR raw A52 stream");
          }
        }

        if (G_LIKELY (stream_type == -1)) {
          /* new id is in the first byte */
          id = map.data[offset++];
          datalen--;

          /* and remap */
          stream_type = demux->psm[id];

          /* Now, if it's a subpicture stream - no more, otherwise
           * take the first byte too, since it's the frame count in audio
           * streams and our backwards compat convention is to strip it off */
          if (stream_type != ST_PS_DVD_SUBPICTURE) {
            /* Number of audio frames in this packet */
#ifndef GST_DISABLE_GST_DEBUG
            guint8 nframes;

            nframes = map.data[offset];
            GST_LOG_OBJECT (demux, "private type 0x%02x, %d frames", id,
                nframes);
#endif
            offset++;
            datalen--;
          } else {
            GST_LOG_OBJECT (demux, "private type 0x%02x, stream type %d", id,
                stream_type);
          }
        }
      }
      if (stream_type == -1)
        goto unknown_stream_type;
    }
    if (filter->pts != -1) {
      demux->next_pts = filter->pts + demux->scr_adjust;
      GST_LOG_OBJECT (demux, "stream 0x%02x PTS = orig %" G_GUINT64_FORMAT
          " (%" G_GUINT64_FORMAT ")", id, filter->pts, demux->next_pts);
    } else
      demux->next_pts = G_MAXUINT64;

    if (filter->dts != -1) {
      demux->next_dts = filter->dts + demux->scr_adjust;
      GST_LOG_OBJECT (demux, "stream 0x%02x DTS = orig %" G_GUINT64_FORMAT
          " (%" G_GUINT64_FORMAT ")", id, filter->dts, demux->next_dts);
    } else {
      demux->next_dts = demux->next_pts;
    }

    demux->current_stream = gst_ps_demux_get_stream (demux, id, stream_type);
  }

  if (G_UNLIKELY (demux->current_stream == NULL)) {
    GST_DEBUG_OBJECT (demux, "Dropping buffer for unknown stream id 0x%02x",
        id);
    goto done;
  }

  /* After 2 seconds of bitstream emit no more pads */
  if (demux->need_no_more_pads
      && (demux->current_scr - demux->first_scr) > 2 * CLOCK_FREQ) {
    GST_DEBUG_OBJECT (demux, "no more pads, notifying");
    gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
    demux->need_no_more_pads = FALSE;
  }

  /* If the stream is not-linked, don't bother creating a sub-buffer
   * to send to it, unless we're processing a discont (which resets
   * the not-linked status and tries again */
  if (demux->current_stream->discont) {
    GST_DEBUG_OBJECT (demux, "stream is discont");
    demux->current_stream->notlinked = FALSE;
  }

  if (demux->current_stream->notlinked == FALSE) {
    out_buf =
        gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, datalen);

    ret = gst_ps_demux_send_data (demux, demux->current_stream, out_buf);
    if (ret == GST_FLOW_NOT_LINKED) {
      demux->current_stream->notlinked = TRUE;
    }
  }

done:
  gst_buffer_unmap (buffer, &map);
  gst_buffer_unref (buffer);

  return ret;

  /* ERRORS */
unknown_stream_type:
  {
    GST_DEBUG_OBJECT (demux, "unknown stream type %02x", id);
    ret = GST_FLOW_OK;
    goto done;
  }
}

static gboolean
gst_ps_demux_resync (GstPsDemux * demux, gboolean save)
{
  const guint8 *data;
  gint avail;
  guint32 code;
  gint offset;
  gboolean found;

  avail = gst_adapter_available (demux->adapter);
  if (G_UNLIKELY (avail < 4))
    goto need_data;

  /* Common case, read 4 bytes an check it */
  data = gst_adapter_map (demux->adapter, 4);

  /* read currect code */
  code = GST_READ_UINT32_BE (data);

  /* The common case is that the sync code is at 0 bytes offset */
  if (G_LIKELY ((code & 0xffffff00) == 0x100L)) {
    GST_LOG_OBJECT (demux, "Found resync code %08x after 0 bytes", code);
    demux->last_sync_code = code;
    gst_adapter_unmap (demux->adapter);
    return TRUE;
  }

  /* Otherwise, we are starting at byte 4 and we need to search
     the sync code in all available data in the adapter */
  offset = 4;
  if (offset >= avail)
    goto need_data;             /* Not enough data to find sync */

  data = gst_adapter_map (demux->adapter, avail);

  do {
    code = (code << 8) | data[offset++];
    found = (code & 0xffffff00) == 0x100L;
  } while (offset < avail && !found);

  gst_adapter_unmap (demux->adapter);

  if (!save || demux->sink_segment.rate >= 0.0) {
    GST_LOG_OBJECT (demux, "flushing %d bytes", offset - 4);
    /* forward playback, we can discard and flush the skipped bytes */
    gst_adapter_flush (demux->adapter, offset - 4);
    ADAPTER_OFFSET_FLUSH (offset - 4);
  } else {
    if (found) {
      GST_LOG_OBJECT (demux, "reverse saving %d bytes", offset - 4);
      /* reverse playback, we keep the flushed bytes and we will append them to
       * the next buffer in the chain function, which is the previous buffer in
       * the stream. */
      gst_adapter_push (demux->rev_adapter,
          gst_adapter_take_buffer (demux->adapter, offset - 4));
    } else {
      GST_LOG_OBJECT (demux, "reverse saving %d bytes", avail);
      /* nothing found, keep all bytes */
      gst_adapter_push (demux->rev_adapter,
          gst_adapter_take_buffer (demux->adapter, avail));
    }
  }

  if (found) {
    GST_LOG_OBJECT (demux, "Found resync code %08x after %d bytes",
        code, offset - 4);
    demux->last_sync_code = code;
  } else {
    GST_LOG_OBJECT (demux, "No resync after skipping %d", offset);
  }

  return found;

need_data:
  {
    GST_LOG_OBJECT (demux, "we need more data for resync %d", avail);
    return FALSE;
  }
}

static inline gboolean
gst_ps_demux_is_pes_sync (guint32 sync)
{
  return ((sync & 0xfc) == 0xbc) ||
      ((sync & 0xe0) == 0xc0) || ((sync & 0xf0) == 0xe0);
}

static inline gboolean
gst_ps_demux_scan_ts (GstPsDemux * demux, const guint8 * data,
    SCAN_MODE mode, guint64 * rts)
{
  gboolean ret = FALSE;
  guint32 scr1, scr2;
  guint64 scr;
  guint64 pts, dts;
  guint32 code;

  /* read the 4 bytes for the sync code */
  code = GST_READ_UINT32_BE (data);
  if (G_LIKELY (code != ID_PS_PACK_START_CODE))
    goto beach;

  /* skip start code */
  data += 4;

  scr1 = GST_READ_UINT32_BE (data);
  scr2 = GST_READ_UINT32_BE (data + 4);

  /* start parsing the stream */
  if ((*data & 0xc0) == 0x40) {
    guint32 scr_ext;
    guint32 next32;
    guint8 stuffing_bytes;

    /* :2=01 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 */

    /* check markers */
    if ((scr1 & 0xc4000400) != 0x44000400)
      goto beach;

    scr = ((guint64) scr1 & 0x38000000) << 3;
    scr |= ((guint64) scr1 & 0x03fff800) << 4;
    scr |= ((guint64) scr1 & 0x000003ff) << 5;
    scr |= ((guint64) scr2 & 0xf8000000) >> 27;

    /* marker:1==1 ! scr_ext:9 ! marker:1==1 */
    if ((scr2 & 0x04010000) != 0x04010000)
      goto beach;

    scr_ext = (scr2 & 0x03fe0000) >> 17;

    if (scr_ext) {
      scr = (scr * 300 + scr_ext % 300) / 300;
    }
    /* SCR has been converted into units of 90Khz ticks to make it comparable
       to DTS/PTS, that also implies 1 tick rounding error */
    data += 6;
    /* PMR:22 ! :2==11 ! reserved:5 ! stuffing_len:3 */
    next32 = GST_READ_UINT32_BE (data);
    if ((next32 & 0x00000300) != 0x00000300)
      goto beach;

    stuffing_bytes = (next32 & 0x07);
    data += 4;
    while (stuffing_bytes--) {
      if (*data++ != 0xff)
        goto beach;
    }
  } else {
    /* check markers */
    if ((scr1 & 0xf1000100) != 0x21000100)
      goto beach;

    if ((scr2 & 0x01800001) != 0x01800001)
      goto beach;

    /* :4=0010 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 ! marker:1==1 */
    scr = ((guint64) scr1 & 0x0e000000) << 5;
    scr |= ((guint64) scr1 & 0x00fffe00) << 6;
    scr |= ((guint64) scr1 & 0x000000ff) << 7;
    scr |= ((guint64) scr2 & 0xfe000000) >> 25;
    data += 8;
  }

  if (mode == SCAN_SCR) {
    *rts = scr;
    ret = TRUE;
    goto beach;
  }

  /* read the 4 bytes for the PES sync code */
  code = GST_READ_UINT32_BE (data);
  if (!gst_ps_demux_is_pes_sync (code))
    goto beach;

  switch (code) {
    case ID_PS_PROGRAM_STREAM_MAP:
    case ID_PRIVATE_STREAM_2:
    case ID_ECM_STREAM:
    case ID_EMM_STREAM:
    case ID_PROGRAM_STREAM_DIRECTORY:
    case ID_DSMCC_STREAM:
    case ID_ITU_TREC_H222_TYPE_E_STREAM:
    case ID_PADDING_STREAM:
      goto beach;
    default:
      break;
  }

  /* skip sync code and size */
  data += 6;

  pts = dts = -1;

  /* stuffing bits, first two bits are '10' for mpeg2 pes so this code is
   * not triggered. */
  while (TRUE) {
    if (*data != 0xff)
      break;
    data++;
  }

  /* STD buffer size, never for mpeg2 */
  if ((*data & 0xc0) == 0x40)
    data += 2;

  /* PTS but no DTS, never for mpeg2 */
  if ((*data & 0xf0) == 0x20) {
    READ_TS (data, pts, beach);
  }
  /* PTS and DTS, never for mpeg2 */
  else if ((*data & 0xf0) == 0x30) {
    READ_TS (data, pts, beach);
    READ_TS (data, dts, beach);
  } else if ((*data & 0xc0) == 0x80) {
    /* mpeg2 case */
    guchar flags;

    /* 2: '10'
     * 2: PES_scrambling_control
     * 1: PES_priority
     * 1: data_alignment_indicator
     * 1: copyright
     * 1: original_or_copy
     */
    flags = *data++;

    if ((flags & 0xc0) != 0x80)
      goto beach;

    /* 2: PTS_DTS_flags
     * 1: ESCR_flag
     * 1: ES_rate_flag
     * 1: DSM_trick_mode_flag
     * 1: additional_copy_info_flag
     * 1: PES_CRC_flag
     * 1: PES_extension_flag
     */
    flags = *data++;

    /* 8: PES_header_data_length */
    data++;

    /* only DTS: this is invalid */
    if ((flags & 0xc0) == 0x40)
      goto beach;

    /* check for PTS */
    if ((flags & 0x80)) {
      READ_TS (data, pts, beach);
    }
    /* check for DTS */
    if ((flags & 0x40)) {
      READ_TS (data, dts, beach);
    }
  }

  if (mode == SCAN_DTS && dts != (guint64) - 1) {
    *rts = dts;
    ret = TRUE;
  }

  if (mode == SCAN_PTS && pts != (guint64) - 1) {
    *rts = pts;
    ret = TRUE;
  }
beach:
  return ret;
}

static inline gboolean
gst_ps_demux_scan_forward_ts (GstPsDemux * demux, guint64 * pos,
    SCAN_MODE mode, guint64 * rts, gint limit)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *buffer;
  guint64 offset = *pos;
  gboolean found = FALSE;
  guint64 ts = 0;
  guint scan_sz = (mode == SCAN_SCR ? SCAN_SCR_SZ : SCAN_PTS_SZ);
  guint cursor, to_read = BLOCK_SZ;
  guint end_scan;
  GstMapInfo map;

  do {
    if (offset + scan_sz > demux->sink_segment.stop)
      return FALSE;

    if (limit && offset > *pos + limit)
      return FALSE;

    if (offset + to_read > demux->sink_segment.stop)
      to_read = demux->sink_segment.stop - offset;

    /* read some data */
    buffer = NULL;
    ret = gst_pad_pull_range (demux->sinkpad, offset, to_read, &buffer);
    if (G_UNLIKELY (ret != GST_FLOW_OK))
      return FALSE;
    gst_buffer_map (buffer, &map, GST_MAP_READ);

    /* may get a short buffer at the end of the file */
    if (G_UNLIKELY (map.size <= scan_sz)) {
      gst_buffer_unmap (buffer, &map);
      gst_buffer_unref (buffer);
      return FALSE;
    }

    end_scan = map.size - scan_sz;

    /* scan the block */
    for (cursor = 0; !found && cursor <= end_scan; cursor++) {
      found = gst_ps_demux_scan_ts (demux, map.data + cursor, mode, &ts);
    }

    /* done with the buffer, unref it */
    gst_buffer_unmap (buffer, &map);
    gst_buffer_unref (buffer);

    if (found) {
      *rts = ts;
      *pos = offset + cursor - 1;
    } else {
      offset += cursor;
    }
  } while (!found && offset < demux->sink_segment.stop);

  return found;
}

static inline gboolean
gst_ps_demux_scan_backward_ts (GstPsDemux * demux, guint64 * pos,
    SCAN_MODE mode, guint64 * rts, gint limit)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *buffer;
  guint64 offset = *pos;
  gboolean found = FALSE;
  guint64 ts = 0;
  guint scan_sz = (mode == SCAN_SCR ? SCAN_SCR_SZ : SCAN_PTS_SZ);
  guint cursor, to_read = BLOCK_SZ;
  guint start_scan;
  guint8 *data;
  GstMapInfo map;

  do {
    if (offset < scan_sz - 1)
      return FALSE;

    if (limit && offset < *pos - limit)
      return FALSE;

    if (offset > BLOCK_SZ)
      offset -= BLOCK_SZ;
    else {
      to_read = offset + 1;
      offset = 0;
    }
    /* read some data */
    buffer = NULL;
    ret = gst_pad_pull_range (demux->sinkpad, offset, to_read, &buffer);
    if (G_UNLIKELY (ret != GST_FLOW_OK))
      return FALSE;

    gst_buffer_map (buffer, &map, GST_MAP_READ);

    /* may get a short buffer at the end of the file */
    if (G_UNLIKELY (map.size <= scan_sz)) {
      gst_buffer_unmap (buffer, &map);
      gst_buffer_unref (buffer);
      return FALSE;
    }

    start_scan = map.size - scan_sz;
    data = map.data + start_scan;

    /* scan the block */
    for (cursor = (start_scan + 1); !found && cursor > 0; cursor--) {
      found = gst_ps_demux_scan_ts (demux, data--, mode, &ts);
    }

    /* done with the buffer, unref it */
    gst_buffer_unmap (buffer, &map);
    gst_buffer_unref (buffer);

    if (found) {
      *rts = ts;
      *pos = offset + cursor;
    }

  } while (!found && offset > 0);

  return found;
}

static inline gboolean
gst_ps_sink_get_duration (GstPsDemux * demux)
{
  gboolean res = FALSE;
  GstPad *peer;
  GstFormat format = GST_FORMAT_BYTES;
  gint64 length = 0;
  guint64 offset;
  guint i;
  guint64 scr = 0;

  /* init the sink segment */
  gst_segment_init (&demux->sink_segment, format);

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

  res = gst_pad_query_duration (peer, format, &length);
  gst_object_unref (peer);

  if (!res || length <= 0)
    goto beach;

  GST_DEBUG_OBJECT (demux, "file length %" G_GINT64_FORMAT, length);

  /* update the sink segment */
  demux->sink_segment.stop = length;
  gst_segment_set_duration (&demux->sink_segment, format, length);
  gst_segment_set_position (&demux->sink_segment, format, 0);

  /* Scan for notorious SCR and PTS to calculate the duration */
  /* scan for first SCR in the stream */
  offset = demux->sink_segment.start;
  gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &demux->first_scr,
      DURATION_SCAN_LIMIT);
  GST_DEBUG_OBJECT (demux, "First SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
      " in packet starting at %" G_GUINT64_FORMAT,
      demux->first_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)),
      offset);
  demux->first_scr_offset = offset;
  /* scan for last SCR in the stream */
  offset = demux->sink_segment.stop;
  gst_ps_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &demux->last_scr, 0);
  GST_DEBUG_OBJECT (demux, "Last SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
      " in packet starting at %" G_GUINT64_FORMAT,
      demux->last_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_scr)),
      offset);
  demux->last_scr_offset = offset;
  /* scan for first PTS in the stream */
  offset = demux->sink_segment.start;
  gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_PTS, &demux->first_pts,
      DURATION_SCAN_LIMIT);
  GST_DEBUG_OBJECT (demux, "First PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
      " in packet starting at %" G_GUINT64_FORMAT,
      demux->first_pts, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_pts)),
      offset);
  if (demux->first_pts != G_MAXUINT64) {
    /* scan for last PTS in the stream */
    offset = demux->sink_segment.stop;
    gst_ps_demux_scan_backward_ts (demux, &offset, SCAN_PTS,
        &demux->last_pts, DURATION_SCAN_LIMIT);
    GST_DEBUG_OBJECT (demux,
        "Last PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
        " in packet starting at %" G_GUINT64_FORMAT, demux->last_pts,
        GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_pts)), offset);
  }
  /* Detect wrong SCR values */
  if (demux->first_scr > demux->last_scr) {
    GST_DEBUG_OBJECT (demux, "Wrong SCR values detected, searching for "
        "a better first SCR value");
    offset = demux->first_scr_offset;
    for (i = 0; i < 10; i++) {
      offset++;
      gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &scr, 0);
      if (scr < demux->last_scr) {
        demux->first_scr = scr;
        demux->first_scr_offset = offset;
        /* Start demuxing from the right place */
        demux->sink_segment.position = offset;
        GST_DEBUG_OBJECT (demux, "Replaced First SCR: %" G_GINT64_FORMAT
            " %" GST_TIME_FORMAT " in packet starting at %" G_GUINT64_FORMAT,
            demux->first_scr,
            GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)), offset);
        break;
      }
    }
  }
  /* Set the base_time and avg rate */
  demux->base_time = MPEGTIME_TO_GSTTIME (demux->first_scr);
  demux->scr_rate_n = demux->last_scr_offset - demux->first_scr_offset;
  demux->scr_rate_d = demux->last_scr - demux->first_scr;

  if (G_LIKELY (demux->first_pts != G_MAXUINT64 &&
          demux->last_pts != G_MAXUINT64)) {
    /* update the src segment */
    demux->src_segment.format = GST_FORMAT_TIME;
    demux->src_segment.start =
        MPEGTIME_TO_GSTTIME (demux->first_pts) - demux->base_time;
    demux->src_segment.stop = -1;
    gst_segment_set_duration (&demux->src_segment, GST_FORMAT_TIME,
        MPEGTIME_TO_GSTTIME (demux->last_pts - demux->first_pts));
    gst_segment_set_position (&demux->src_segment, GST_FORMAT_TIME,
        demux->src_segment.start);
  }
  GST_INFO_OBJECT (demux, "sink segment configured %" GST_SEGMENT_FORMAT,
      &demux->sink_segment);
  GST_INFO_OBJECT (demux, "src segment configured %" GST_SEGMENT_FORMAT,
      &demux->src_segment);

  res = TRUE;

beach:
  return res;
}

static inline GstFlowReturn
gst_ps_demux_pull_block (GstPad * pad, GstPsDemux * demux,
    guint64 offset, guint size)
{
  GstFlowReturn ret;
  GstBuffer *buffer = NULL;

  ret = gst_pad_pull_range (pad, offset, size, &buffer);
  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    GST_DEBUG_OBJECT (demux, "pull range at %" G_GUINT64_FORMAT
        " size %u failed", offset, size);
    goto beach;
  } else
    GST_LOG_OBJECT (demux, "pull range at %" G_GUINT64_FORMAT
        " size %u done", offset, size);

  if (demux->sink_segment.rate < 0) {
    GST_LOG_OBJECT (demux, "setting discont flag on backward rate");
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
  }
  ret = gst_ps_demux_chain (pad, GST_OBJECT (demux), buffer);

beach:
  return ret;
}

static void
gst_ps_demux_loop (GstPad * pad)
{
  GstPsDemux *demux;
  GstFlowReturn ret = GST_FLOW_OK;
  guint64 offset = 0;

  demux = GST_PS_DEMUX (gst_pad_get_parent (pad));

  if (G_UNLIKELY (demux->flushing)) {
    ret = GST_FLOW_FLUSHING;
    goto pause;
  }

  if (G_UNLIKELY (demux->sink_segment.format == GST_FORMAT_UNDEFINED))
    gst_ps_sink_get_duration (demux);

  offset = demux->sink_segment.position;
  if (demux->sink_segment.rate >= 0) {
    guint size = BLOCK_SZ;
    if (G_LIKELY (demux->sink_segment.stop != (guint64) - 1)) {
      size = MIN (size, demux->sink_segment.stop - offset);
    }
    /* pull in data */
    ret = gst_ps_demux_pull_block (pad, demux, offset, size);

    /* pause if something went wrong */
    if (G_UNLIKELY (ret != GST_FLOW_OK))
      goto pause;

    /* update our position */
    offset += size;
    gst_segment_set_position (&demux->sink_segment, GST_FORMAT_BYTES, offset);

    /* check EOS condition */
    if ((demux->src_segment.flags & GST_SEEK_FLAG_SEGMENT) &&
        ((demux->sink_segment.position >= demux->sink_segment.stop) ||
            (demux->src_segment.stop != (guint64) - 1 &&
                demux->src_segment.position >= demux->src_segment.stop))) {
      GST_DEBUG_OBJECT (demux, "forward mode using segment reached end of "
          "segment pos %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
          " pos in bytes %" G_GUINT64_FORMAT " stop in bytes %"
          G_GUINT64_FORMAT, GST_TIME_ARGS (demux->src_segment.position),
          GST_TIME_ARGS (demux->src_segment.stop),
          demux->sink_segment.position, demux->sink_segment.stop);
      ret = GST_FLOW_EOS;
      goto pause;
    }
  } else {                      /* Reverse playback */
    guint64 size = MIN (offset, BLOCK_SZ);

    /* pull in data */
    ret = gst_ps_demux_pull_block (pad, demux, offset - size, size);

    /* pause if something went wrong */
    if (G_UNLIKELY (ret != GST_FLOW_OK))
      goto pause;

    /* update our position */
    offset -= size;
    gst_segment_set_position (&demux->sink_segment, GST_FORMAT_BYTES, offset);

    /* check EOS condition */
    if (demux->sink_segment.position <= demux->sink_segment.start ||
        demux->src_segment.position <= demux->src_segment.start) {
      GST_DEBUG_OBJECT (demux, "reverse mode using segment reached end of "
          "segment pos %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
          " pos in bytes %" G_GUINT64_FORMAT " stop in bytes %"
          G_GUINT64_FORMAT, GST_TIME_ARGS (demux->src_segment.position),
          GST_TIME_ARGS (demux->src_segment.start),
          demux->sink_segment.position, demux->sink_segment.start);
      ret = GST_FLOW_EOS;
      goto pause;
    }
  }

  gst_object_unref (demux);

  return;

pause:
  {
    const gchar *reason = gst_flow_get_name (ret);

    GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
    gst_pad_pause_task (pad);

    if (ret == GST_FLOW_EOS) {
      /* perform EOS logic */
      gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
      if (demux->src_segment.flags & GST_SEEK_FLAG_SEGMENT) {
        gint64 stop;

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

        if (demux->sink_segment.rate >= 0) {
          GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
          gst_element_post_message (GST_ELEMENT_CAST (demux),
              gst_message_new_segment_done (GST_OBJECT_CAST (demux),
                  GST_FORMAT_TIME, stop));
          gst_ps_demux_send_event (demux,
              gst_event_new_segment_done (GST_FORMAT_TIME, stop));
        } else {                /* Reverse playback */
          GST_LOG_OBJECT (demux, "Sending segment done, at beginning of "
              "segment");
          gst_element_post_message (GST_ELEMENT_CAST (demux),
              gst_message_new_segment_done (GST_OBJECT_CAST (demux),
                  GST_FORMAT_TIME, demux->src_segment.start));
          gst_ps_demux_send_event (demux,
              gst_event_new_segment_done (GST_FORMAT_TIME,
                  demux->src_segment.start));
        }
      } else {
        /* normal playback, send EOS to all linked pads */
        gst_element_no_more_pads (GST_ELEMENT (demux));
        GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
        if (!gst_ps_demux_send_event (demux, gst_event_new_eos ())
            && !have_open_streams (demux)) {
          GST_WARNING_OBJECT (demux, "EOS and no streams open");
          GST_ELEMENT_ERROR (demux, STREAM, FAILED,
              ("Internal data stream error."), ("No valid streams detected"));
        }
      }
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
      GST_ELEMENT_ERROR (demux, STREAM, FAILED,
          ("Internal data stream error."),
          ("stream stopped, reason %s", reason));
      gst_ps_demux_send_event (demux, gst_event_new_eos ());
    }

    gst_object_unref (demux);
    return;
  }
}

/* If we can pull that's prefered */
static gboolean
gst_ps_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
{
  gboolean res = FALSE;
  GstQuery *query = gst_query_new_scheduling ();

  if (gst_pad_peer_query (sinkpad, query)) {
    if (gst_query_has_scheduling_mode_with_flags (query,
            GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE)) {
      res = gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
    } else {
      res = gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
    }
  } else {
    res = gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
  }

  gst_query_unref (query);

  return res;
}

/* This function gets called when we activate ourselves in push mode. */
static gboolean
gst_ps_demux_sink_activate_push (GstPad * sinkpad, GstObject * parent,
    gboolean active)
{
  GstPsDemux *demux = GST_PS_DEMUX (parent);

  demux->random_access = FALSE;

  return TRUE;
}

/* this function gets called when we activate ourselves in pull mode.
 * We can perform  random access to the resource and we start a task
 * to start reading */
static gboolean
gst_ps_demux_sink_activate_pull (GstPad * sinkpad, GstObject * parent,
    gboolean active)
{
  GstPsDemux *demux = GST_PS_DEMUX (parent);

  if (active) {
    GST_DEBUG ("pull mode activated");
    demux->random_access = TRUE;
    return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ps_demux_loop,
        sinkpad, NULL);
  } else {
    demux->random_access = FALSE;
    return gst_pad_stop_task (sinkpad);
  }
}

static gboolean
gst_ps_demux_sink_activate_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  if (mode == GST_PAD_MODE_PUSH) {
    return gst_ps_demux_sink_activate_push (pad, parent, active);
  } else if (mode == GST_PAD_MODE_PULL) {
    return gst_ps_demux_sink_activate_pull (pad, parent, active);
  }
  return FALSE;
}

/* EOS and NOT_LINKED need to be combined. This means that we return:
*
*  GST_FLOW_NOT_LINKED: when all pads NOT_LINKED.
*  GST_FLOW_EOS: when all pads EOS or NOT_LINKED.
*/
static GstFlowReturn
gst_ps_demux_combine_flows (GstPsDemux * demux, GstFlowReturn ret)
{
  GST_LOG_OBJECT (demux, "flow return: %s", gst_flow_get_name (ret));

  ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);

  if (G_UNLIKELY (demux->need_no_more_pads && ret == GST_FLOW_NOT_LINKED))
    ret = GST_FLOW_OK;

  GST_LOG_OBJECT (demux, "combined flow return: %s", gst_flow_get_name (ret));
  return ret;
}

static GstFlowReturn
gst_ps_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstPsDemux *demux = GST_PS_DEMUX (parent);
  GstFlowReturn ret = GST_FLOW_OK;
  guint32 avail;
  gboolean save, discont;

  discont = GST_BUFFER_IS_DISCONT (buffer);

  if (discont) {
    GST_LOG_OBJECT (demux, "Received buffer with discont flag and"
        " offset %" G_GUINT64_FORMAT, GST_BUFFER_OFFSET (buffer));

    gst_pes_filter_drain (&demux->filter);
    gst_ps_demux_mark_discont (demux, TRUE, FALSE);

    /* mark discont on all streams */
    if (demux->sink_segment.rate >= 0.0) {
      demux->current_scr = G_MAXUINT64;
      demux->bytes_since_scr = 0;
    }
  } else {
    GST_LOG_OBJECT (demux, "Received buffer with offset %" G_GUINT64_FORMAT,
        GST_BUFFER_OFFSET (buffer));
  }

  /* We keep the offset to interpolate SCR */
  demux->adapter_offset = GST_BUFFER_OFFSET (buffer);

  gst_adapter_push (demux->adapter, buffer);
  demux->bytes_since_scr += gst_buffer_get_size (buffer);

  avail = gst_adapter_available (demux->rev_adapter);
  if (avail > 0) {
    GST_LOG_OBJECT (demux, "appending %u saved bytes", avail);
    /* if we have a previous reverse chunk, append this now */
    /* FIXME this code assumes we receive discont buffers all thei
     * time */
    gst_adapter_push (demux->adapter,
        gst_adapter_take_buffer (demux->rev_adapter, avail));
  }

  avail = gst_adapter_available (demux->adapter);
  GST_LOG_OBJECT (demux, "avail now: %d, state %d", avail, demux->filter.state);

  switch (demux->filter.state) {
    case STATE_DATA_SKIP:
    case STATE_DATA_PUSH:
      ret = gst_pes_filter_process (&demux->filter);
      break;
    case STATE_HEADER_PARSE:
      break;
    default:
      break;
  }

  switch (ret) {
    case GST_FLOW_NEED_MORE_DATA:
      /* Go and get more data */
      ret = GST_FLOW_OK;
      goto done;
    case GST_FLOW_LOST_SYNC:
      /* for FLOW_OK or lost-sync, carry onto resync */
      ret = GST_FLOW_OK;
      break;
    case GST_FLOW_OK:
      break;
    default:
      /* Any other return value should be sent upstream immediately */
      goto done;
  }

  /* align adapter data to sync boundary, we keep the data up to the next sync
   * point. */
  save = TRUE;
  while (gst_ps_demux_resync (demux, save)) {
    gboolean ps_sync = TRUE;
    if (G_UNLIKELY (demux->flushing)) {
      ret = GST_FLOW_FLUSHING;
      goto done;
    }

    /* now switch on last synced byte */
    switch (demux->last_sync_code) {
      case ID_PS_PACK_START_CODE:
        ret = gst_ps_demux_parse_pack_start (demux);
        break;
      case ID_PS_SYSTEM_HEADER_START_CODE:
        ret = gst_ps_demux_parse_sys_head (demux);
        break;
      case ID_PS_END_CODE:
        /* Skip final 4 bytes */
        gst_adapter_flush (demux->adapter, 4);
        ADAPTER_OFFSET_FLUSH (4);
        ret = GST_FLOW_OK;
        goto done;
      case ID_PS_PROGRAM_STREAM_MAP:
        ret = gst_ps_demux_parse_psm (demux);
        break;
      default:
        if (gst_ps_demux_is_pes_sync (demux->last_sync_code)) {
          ret = gst_pes_filter_process (&demux->filter);
        } else {
          GST_DEBUG_OBJECT (demux, "sync_code=%08x, non PES sync found"
              ", continuing", demux->last_sync_code);
          ps_sync = FALSE;
          ret = GST_FLOW_LOST_SYNC;
        }
        break;
    }
    /* if we found a ps sync, we stop saving the data, any non-ps sync gets
     * saved up to the next ps sync. */
    if (ps_sync)
      save = FALSE;

    switch (ret) {
      case GST_FLOW_NEED_MORE_DATA:
        GST_DEBUG_OBJECT (demux, "need more data");
        ret = GST_FLOW_OK;
        goto done;
      case GST_FLOW_LOST_SYNC:
        if (!save || demux->sink_segment.rate >= 0.0) {
          GST_DEBUG_OBJECT (demux, "flushing 3 bytes");
          gst_adapter_flush (demux->adapter, 3);
          ADAPTER_OFFSET_FLUSH (3);
        } else {
          GST_DEBUG_OBJECT (demux, "saving 3 bytes");
          gst_adapter_push (demux->rev_adapter,
              gst_adapter_take_buffer (demux->adapter, 3));
        }
        ret = GST_FLOW_OK;
        break;
      default:
        ret = gst_ps_demux_combine_flows (demux, ret);
        if (ret != GST_FLOW_OK)
          goto done;
        break;
    }
  }
done:
  return ret;
}

static GstStateChangeReturn
gst_ps_demux_change_state (GstElement * element, GstStateChange transition)
{
  GstPsDemux *demux = GST_PS_DEMUX (element);
  GstStateChangeReturn result;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      gst_pes_filter_init (&demux->filter, demux->adapter,
          &demux->adapter_offset);
      gst_pes_filter_set_callbacks (&demux->filter,
          (GstPESFilterData) gst_ps_demux_data_cb,
          (GstPESFilterResync) gst_ps_demux_resync_cb, demux);
      demux->filter.gather_pes = TRUE;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_ps_demux_reset (demux);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_pes_filter_uninit (&demux->filter);
      break;
    default:
      break;
  }

  return result;
}

static void
gst_segment_set_position (GstSegment * segment, GstFormat format,
    guint64 position)
{
  if (segment->format == GST_FORMAT_UNDEFINED) {
    segment->format = format;
  }
  segment->position = position;
}

static void
gst_segment_set_duration (GstSegment * segment, GstFormat format,
    guint64 duration)
{
  if (segment->format == GST_FORMAT_UNDEFINED) {
    segment->format = format;
  }
  segment->duration = duration;
}
