/* GStreamer
 * Copyright (C) 2005-2007 Wim Taymans <wim.taymans@gmail.com>
 *
 * gstbasesink.c: Base class for sink elements
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:gstbasesink
 * @short_description: Base class for sink elements
 * @see_also: #GstBaseTransform, #GstBaseSrc
 *
 * #GstBaseSink is the base class for sink elements in GStreamer, such as
 * xvimagesink or filesink. It is a layer on top of #GstElement that provides a
 * simplified interface to plugin writers. #GstBaseSink handles many details
 * for you, for example: preroll, clock synchronization, state changes,
 * activation in push or pull mode, and queries.
 *
 * In most cases, when writing sink elements, there is no need to implement
 * class methods from #GstElement or to set functions on pads, because the
 * #GstBaseSink infrastructure should be sufficient.
 *
 * #GstBaseSink provides support for exactly one sink pad, which should be
 * named "sink". A sink implementation (subclass of #GstBaseSink) should
 * install a pad template in its class_init function, like so:
 * |[
 * static void
 * my_element_class_init (GstMyElementClass *klass)
 * {
 *   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
 *
 *   // sinktemplate should be a #GstStaticPadTemplate with direction
 *   // #GST_PAD_SINK and name "sink"
 *   gst_element_class_add_pad_template (gstelement_class,
 *       gst_static_pad_template_get (&amp;sinktemplate));
 *
 *   gst_element_class_set_static_metadata (gstelement_class,
 *       "Sink name",
 *       "Sink",
 *       "My Sink element",
 *       "The author &lt;my.sink@my.email&gt;");
 * }
 * ]|
 *
 * #GstBaseSink will handle the prerolling correctly. This means that it will
 * return #GST_STATE_CHANGE_ASYNC from a state change to PAUSED until the first
 * buffer arrives in this element. The base class will call the
 * #GstBaseSinkClass.preroll() vmethod with this preroll buffer and will then
 * commit the state change to the next asynchronously pending state.
 *
 * When the element is set to PLAYING, #GstBaseSink will synchronise on the
 * clock using the times returned from #GstBaseSinkClass.get_times(). If this
 * function returns #GST_CLOCK_TIME_NONE for the start time, no synchronisation
 * will be done. Synchronisation can be disabled entirely by setting the object
 * #GstBaseSink:sync property to %FALSE.
 *
 * After synchronisation the virtual method #GstBaseSinkClass.render() will be
 * called. Subclasses should minimally implement this method.
 *
 * Subclasses that synchronise on the clock in the #GstBaseSinkClass.render()
 * method are supported as well. These classes typically receive a buffer in
 * the render method and can then potentially block on the clock while
 * rendering. A typical example is an audiosink.
 * These subclasses can use gst_base_sink_wait_preroll() to perform the
 * blocking wait.
 *
 * Upon receiving the EOS event in the PLAYING state, #GstBaseSink will wait
 * for the clock to reach the time indicated by the stop time of the last
 * #GstBaseSinkClass.get_times() call before posting an EOS message. When the
 * element receives EOS in PAUSED, preroll completes, the event is queued and an
 * EOS message is posted when going to PLAYING.
 *
 * #GstBaseSink will internally use the #GST_EVENT_NEWSEGMENT events to schedule
 * synchronisation and clipping of buffers. Buffers that fall completely outside
 * of the current segment are dropped. Buffers that fall partially in the
 * segment are rendered (and prerolled). Subclasses should do any subbuffer
 * clipping themselves when needed.
 *
 * #GstBaseSink will by default report the current playback position in
 * #GST_FORMAT_TIME based on the current clock time and segment information.
 * If no clock has been set on the element, the query will be forwarded
 * upstream.
 *
 * The #GstBaseSinkClass.set_caps() function will be called when the subclass
 * should configure itself to process a specific media type.
 *
 * The #GstBaseSinkClass.start() and #GstBaseSinkClass.stop() virtual methods
 * will be called when resources should be allocated. Any 
 * #GstBaseSinkClass.preroll(), #GstBaseSinkClass.render() and
 * #GstBaseSinkClass.set_caps() function will be called between the
 * #GstBaseSinkClass.start() and #GstBaseSinkClass.stop() calls.
 *
 * The #GstBaseSinkClass.event() virtual method will be called when an event is
 * received by #GstBaseSink. Normally this method should only be overriden by
 * very specific elements (such as file sinks) which need to handle the
 * newsegment event specially.
 *
 * The #GstBaseSinkClass.unlock() method is called when the elements should
 * unblock any blocking operations they perform in the
 * #GstBaseSinkClass.render() method. This is mostly useful when the
 * #GstBaseSinkClass.render() method performs a blocking write on a file
 * descriptor, for example.
 *
 * The #GstBaseSink:max-lateness property affects how the sink deals with
 * buffers that arrive too late in the sink. A buffer arrives too late in the
 * sink when the presentation time (as a combination of the last segment, buffer
 * timestamp and element base_time) plus the duration is before the current
 * time of the clock.
 * If the frame is later than max-lateness, the sink will drop the buffer
 * without calling the render method.
 * This feature is disabled if sync is disabled, the
 * #GstBaseSinkClass.get_times() method does not return a valid start time or
 * max-lateness is set to -1 (the default).
 * Subclasses can use gst_base_sink_set_max_lateness() to configure the
 * max-lateness value.
 *
 * The #GstBaseSink:qos property will enable the quality-of-service features of
 * the basesink which gather statistics about the real-time performance of the
 * clock synchronisation. For each buffer received in the sink, statistics are
 * gathered and a QOS event is sent upstream with these numbers. This
 * information can then be used by upstream elements to reduce their processing
 * rate, for example.
 *
 * The #GstBaseSink:async property can be used to instruct the sink to never
 * perform an ASYNC state change. This feature is mostly usable when dealing
 * with non-synchronized streams or sparse streams.
 *
 * Last reviewed on 2007-08-29 (0.10.15)
 */

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

#include <gst/gst_private.h>

#include "gstbasesink.h"
#include <gst/gst-i18n-lib.h>

GST_DEBUG_CATEGORY_STATIC (gst_base_sink_debug);
#define GST_CAT_DEFAULT gst_base_sink_debug

#define GST_BASE_SINK_GET_PRIVATE(obj)  \
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_SINK, GstBaseSinkPrivate))

#define GST_FLOW_STEP GST_FLOW_CUSTOM_ERROR

typedef struct
{
  gboolean valid;               /* if this info is valid */
  guint32 seqnum;               /* the seqnum of the STEP event */
  GstFormat format;             /* the format of the amount */
  guint64 amount;               /* the total amount of data to skip */
  guint64 position;             /* the position in the stepped data */
  guint64 duration;             /* the duration in time of the skipped data */
  guint64 start;                /* running_time of the start */
  gdouble rate;                 /* rate of skipping */
  gdouble start_rate;           /* rate before skipping */
  guint64 start_start;          /* start position skipping */
  guint64 start_stop;           /* stop position skipping */
  gboolean flush;               /* if this was a flushing step */
  gboolean intermediate;        /* if this is an intermediate step */
  gboolean need_preroll;        /* if we need preroll after this step */
} GstStepInfo;

struct _GstBaseSinkPrivate
{
  gint qos_enabled;             /* ATOMIC */
  gboolean async_enabled;
  GstClockTimeDiff ts_offset;
  GstClockTime render_delay;

  /* start, stop of current buffer, stream time, used to report position */
  GstClockTime current_sstart;
  GstClockTime current_sstop;

  /* start, stop and jitter of current buffer, running time */
  GstClockTime current_rstart;
  GstClockTime current_rstop;
  GstClockTimeDiff current_jitter;
  /* the running time of the previous buffer */
  GstClockTime prev_rstart;

  /* EOS sync time in running time */
  GstClockTime eos_rtime;

  /* last buffer that arrived in time, running time */
  GstClockTime last_render_time;
  /* when the last buffer left the sink, running time */
  GstClockTime last_left;

  /* running averages go here these are done on running time */
  GstClockTime avg_pt;
  GstClockTime avg_duration;
  gdouble avg_rate;
  GstClockTime avg_in_diff;

  /* these are done on system time. avg_jitter and avg_render are
   * compared to eachother to see if the rendering time takes a
   * huge amount of the processing, If so we are flooded with
   * buffers. */
  GstClockTime last_left_systime;
  GstClockTime avg_jitter;
  GstClockTime start, stop;
  GstClockTime avg_render;

  /* number of rendered and dropped frames */
  guint64 rendered;
  guint64 dropped;

  /* latency stuff */
  GstClockTime latency;

  /* if we already commited the state */
  gboolean commited;
  /* state change to playing ongoing */
  gboolean to_playing;

  /* when we received EOS */
  gboolean received_eos;

  /* when we are prerolled and able to report latency */
  gboolean have_latency;

  /* the last buffer we prerolled or rendered. Useful for making snapshots */
  gint enable_last_sample;      /* atomic */
  GstBuffer *last_buffer;
  GstCaps *last_caps;

  /* negotiated caps */
  GstCaps *caps;

  /* blocksize for pulling */
  guint blocksize;

  gboolean discont;

  /* seqnum of the stream */
  guint32 seqnum;

  gboolean call_preroll;
  gboolean step_unlock;

  /* we have a pending and a current step operation */
  GstStepInfo current_step;
  GstStepInfo pending_step;

  /* Cached GstClockID */
  GstClockID cached_clock_id;

  /* for throttling and QoS */
  GstClockTime earliest_in_time;
  GstClockTime throttle_time;
};

#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))

/* generic running average, this has a neutral window size */
#define UPDATE_RUNNING_AVG(avg,val)   DO_RUNNING_AVG(avg,val,8)

/* the windows for these running averages are experimentally obtained.
 * possitive values get averaged more while negative values use a small
 * window so we can react faster to badness. */
#define UPDATE_RUNNING_AVG_P(avg,val) DO_RUNNING_AVG(avg,val,16)
#define UPDATE_RUNNING_AVG_N(avg,val) DO_RUNNING_AVG(avg,val,4)

/* BaseSink properties */

#define DEFAULT_CAN_ACTIVATE_PULL FALSE /* fixme: enable me */
#define DEFAULT_CAN_ACTIVATE_PUSH TRUE

#define DEFAULT_SYNC                TRUE
#define DEFAULT_MAX_LATENESS        -1
#define DEFAULT_QOS                 FALSE
#define DEFAULT_ASYNC               TRUE
#define DEFAULT_TS_OFFSET           0
#define DEFAULT_BLOCKSIZE           4096
#define DEFAULT_RENDER_DELAY        0
#define DEFAULT_ENABLE_LAST_SAMPLE  TRUE
#define DEFAULT_THROTTLE_TIME       0

enum
{
  PROP_0,
  PROP_SYNC,
  PROP_MAX_LATENESS,
  PROP_QOS,
  PROP_ASYNC,
  PROP_TS_OFFSET,
  PROP_ENABLE_LAST_SAMPLE,
  PROP_LAST_SAMPLE,
  PROP_BLOCKSIZE,
  PROP_RENDER_DELAY,
  PROP_THROTTLE_TIME,
  PROP_LAST
};

static GstElementClass *parent_class = NULL;

static void gst_base_sink_class_init (GstBaseSinkClass * klass);
static void gst_base_sink_init (GstBaseSink * trans, gpointer g_class);
static void gst_base_sink_finalize (GObject * object);

GType
gst_base_sink_get_type (void)
{
  static volatile gsize base_sink_type = 0;

  if (g_once_init_enter (&base_sink_type)) {
    GType _type;
    static const GTypeInfo base_sink_info = {
      sizeof (GstBaseSinkClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_base_sink_class_init,
      NULL,
      NULL,
      sizeof (GstBaseSink),
      0,
      (GInstanceInitFunc) gst_base_sink_init,
    };

    _type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstBaseSink", &base_sink_info, G_TYPE_FLAG_ABSTRACT);
    g_once_init_leave (&base_sink_type, _type);
  }
  return base_sink_type;
}

static void gst_base_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_base_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_base_sink_send_event (GstElement * element,
    GstEvent * event);
static gboolean default_element_query (GstElement * element, GstQuery * query);

static GstCaps *gst_base_sink_default_get_caps (GstBaseSink * sink,
    GstCaps * caps);
static gboolean gst_base_sink_default_set_caps (GstBaseSink * sink,
    GstCaps * caps);
static void gst_base_sink_default_get_times (GstBaseSink * basesink,
    GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
static gboolean gst_base_sink_set_flushing (GstBaseSink * basesink,
    GstPad * pad, gboolean flushing);
static gboolean gst_base_sink_default_activate_pull (GstBaseSink * basesink,
    gboolean active);
static gboolean gst_base_sink_default_do_seek (GstBaseSink * sink,
    GstSegment * segment);
static gboolean gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
    GstEvent * event, GstSegment * segment);

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

static gboolean gst_base_sink_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstFlowReturn gst_base_sink_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static GstFlowReturn gst_base_sink_chain_list (GstPad * pad, GstObject * parent,
    GstBufferList * list);

static void gst_base_sink_loop (GstPad * pad);
static gboolean gst_base_sink_pad_activate (GstPad * pad, GstObject * parent);
static gboolean gst_base_sink_pad_activate_mode (GstPad * pad,
    GstObject * parent, GstPadMode mode, gboolean active);
static gboolean gst_base_sink_default_event (GstBaseSink * basesink,
    GstEvent * event);
static GstFlowReturn gst_base_sink_default_wait_event (GstBaseSink * basesink,
    GstEvent * event);
static gboolean gst_base_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static gboolean gst_base_sink_default_query (GstBaseSink * sink,
    GstQuery * query);

static gboolean gst_base_sink_negotiate_pull (GstBaseSink * basesink);
static GstCaps *gst_base_sink_default_fixate (GstBaseSink * bsink,
    GstCaps * caps);
static GstCaps *gst_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps);

/* check if an object was too late */
static gboolean gst_base_sink_is_too_late (GstBaseSink * basesink,
    GstMiniObject * obj, GstClockTime rstart, GstClockTime rstop,
    GstClockReturn status, GstClockTimeDiff jitter);

static void
gst_base_sink_class_init (GstBaseSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_base_sink_debug, "basesink", 0,
      "basesink element");

  g_type_class_add_private (klass, sizeof (GstBaseSinkPrivate));

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_base_sink_finalize;
  gobject_class->set_property = gst_base_sink_set_property;
  gobject_class->get_property = gst_base_sink_get_property;

  g_object_class_install_property (gobject_class, PROP_SYNC,
      g_param_spec_boolean ("sync", "Sync", "Sync on the clock", DEFAULT_SYNC,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_MAX_LATENESS,
      g_param_spec_int64 ("max-lateness", "Max Lateness",
          "Maximum number of nanoseconds that a buffer can be late before it "
          "is dropped (-1 unlimited)", -1, G_MAXINT64, DEFAULT_MAX_LATENESS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_QOS,
      g_param_spec_boolean ("qos", "Qos",
          "Generate Quality-of-Service events upstream", DEFAULT_QOS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstBaseSink:async:
   *
   * If set to #TRUE, the basesink will perform asynchronous state changes.
   * When set to #FALSE, the sink will not signal the parent when it prerolls.
   * Use this option when dealing with sparse streams or when synchronisation is
   * not required.
   */
  g_object_class_install_property (gobject_class, PROP_ASYNC,
      g_param_spec_boolean ("async", "Async",
          "Go asynchronously to PAUSED", DEFAULT_ASYNC,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstBaseSink:ts-offset:
   *
   * Controls the final synchronisation, a negative value will render the buffer
   * earlier while a positive value delays playback. This property can be
   * used to fix synchronisation in bad files.
   */
  g_object_class_install_property (gobject_class, PROP_TS_OFFSET,
      g_param_spec_int64 ("ts-offset", "TS Offset",
          "Timestamp offset in nanoseconds", G_MININT64, G_MAXINT64,
          DEFAULT_TS_OFFSET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstBaseSink:enable-last-sample:
   *
   * Enable the last-sample property. If FALSE, basesink doesn't keep a
   * reference to the last buffer arrived and the last-sample property is always
   * set to NULL. This can be useful if you need buffers to be released as soon
   * as possible, eg. if you're using a buffer pool.
   */
  g_object_class_install_property (gobject_class, PROP_ENABLE_LAST_SAMPLE,
      g_param_spec_boolean ("enable-last-sample", "Enable Last Buffer",
          "Enable the last-sample property", DEFAULT_ENABLE_LAST_SAMPLE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstBaseSink:last-sample:
   *
   * The last buffer that arrived in the sink and was used for preroll or for
   * rendering. This property can be used to generate thumbnails. This property
   * can be NULL when the sink has not yet received a bufer.
   */
  g_object_class_install_property (gobject_class, PROP_LAST_SAMPLE,
      g_param_spec_boxed ("last-sample", "Last Sample",
          "The last sample received in the sink", GST_TYPE_SAMPLE,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  /**
   * GstBaseSink:blocksize:
   *
   * The amount of bytes to pull when operating in pull mode.
   */
  /* FIXME 0.11: blocksize property should be int, otherwise min>max.. */
  g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
      g_param_spec_uint ("blocksize", "Block size",
          "Size in bytes to pull per buffer (0 = default)", 0, G_MAXUINT,
          DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstBaseSink:render-delay:
   *
   * The additional delay between synchronisation and actual rendering of the
   * media. This property will add additional latency to the device in order to
   * make other sinks compensate for the delay.
   */
  g_object_class_install_property (gobject_class, PROP_RENDER_DELAY,
      g_param_spec_uint64 ("render-delay", "Render Delay",
          "Additional render delay of the sink in nanoseconds", 0, G_MAXUINT64,
          DEFAULT_RENDER_DELAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstBaseSink:throttle-time:
   *
   * The time to insert between buffers. This property can be used to control
   * the maximum amount of buffers per second to render. Setting this property
   * to a value bigger than 0 will make the sink create THROTTLE QoS events.
   */
  g_object_class_install_property (gobject_class, PROP_THROTTLE_TIME,
      g_param_spec_uint64 ("throttle-time", "Throttle time",
          "The time to keep between rendered buffers", 0, G_MAXUINT64,
          DEFAULT_THROTTLE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_base_sink_change_state);
  gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_base_sink_send_event);
  gstelement_class->query = GST_DEBUG_FUNCPTR (default_element_query);

  klass->get_caps = GST_DEBUG_FUNCPTR (gst_base_sink_default_get_caps);
  klass->set_caps = GST_DEBUG_FUNCPTR (gst_base_sink_default_set_caps);
  klass->fixate = GST_DEBUG_FUNCPTR (gst_base_sink_default_fixate);
  klass->activate_pull =
      GST_DEBUG_FUNCPTR (gst_base_sink_default_activate_pull);
  klass->get_times = GST_DEBUG_FUNCPTR (gst_base_sink_default_get_times);
  klass->query = GST_DEBUG_FUNCPTR (gst_base_sink_default_query);
  klass->event = GST_DEBUG_FUNCPTR (gst_base_sink_default_event);
  klass->wait_event = GST_DEBUG_FUNCPTR (gst_base_sink_default_wait_event);

  /* Registering debug symbols for function pointers */
  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_fixate);
  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate);
  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate_mode);
  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_event);
  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_chain);
  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_chain_list);
  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_sink_query);
}

static GstCaps *
gst_base_sink_query_caps (GstBaseSink * bsink, GstPad * pad, GstCaps * filter)
{
  GstBaseSinkClass *bclass;
  GstCaps *caps = NULL;
  gboolean fixed;

  bclass = GST_BASE_SINK_GET_CLASS (bsink);
  fixed = GST_PAD_IS_FIXED_CAPS (pad);

  if (fixed || bsink->pad_mode == GST_PAD_MODE_PULL) {
    /* if we are operating in pull mode or fixed caps, we only accept the
     * currently negotiated caps */
    caps = gst_pad_get_current_caps (pad);
  }
  if (caps == NULL) {
    if (bclass->get_caps)
      caps = bclass->get_caps (bsink, filter);

    if (caps == NULL) {
      GstPadTemplate *pad_template;

      pad_template =
          gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass),
          "sink");
      if (pad_template != NULL) {
        caps = gst_pad_template_get_caps (pad_template);

        if (filter) {
          GstCaps *intersection;

          intersection =
              gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
          gst_caps_unref (caps);
          caps = intersection;
        }
      }
    }
  }

  return caps;
}

static GstCaps *
gst_base_sink_default_fixate (GstBaseSink * bsink, GstCaps * caps)
{
  GST_DEBUG_OBJECT (bsink, "using default caps fixate function");
  return gst_caps_fixate (caps);
}

static GstCaps *
gst_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps)
{
  GstBaseSinkClass *bclass;

  bclass = GST_BASE_SINK_GET_CLASS (bsink);

  if (bclass->fixate)
    caps = bclass->fixate (bsink, caps);

  return caps;
}

static void
gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
{
  GstPadTemplate *pad_template;
  GstBaseSinkPrivate *priv;

  basesink->priv = priv = GST_BASE_SINK_GET_PRIVATE (basesink);

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
  g_return_if_fail (pad_template != NULL);

  basesink->sinkpad = gst_pad_new_from_template (pad_template, "sink");

  gst_pad_set_activate_function (basesink->sinkpad, gst_base_sink_pad_activate);
  gst_pad_set_activatemode_function (basesink->sinkpad,
      gst_base_sink_pad_activate_mode);
  gst_pad_set_query_function (basesink->sinkpad, gst_base_sink_sink_query);
  gst_pad_set_event_function (basesink->sinkpad, gst_base_sink_event);
  gst_pad_set_chain_function (basesink->sinkpad, gst_base_sink_chain);
  gst_pad_set_chain_list_function (basesink->sinkpad, gst_base_sink_chain_list);
  gst_element_add_pad (GST_ELEMENT_CAST (basesink), basesink->sinkpad);

  basesink->pad_mode = GST_PAD_MODE_NONE;
  g_mutex_init (&basesink->preroll_lock);
  g_cond_init (&basesink->preroll_cond);
  priv->have_latency = FALSE;

  basesink->can_activate_push = DEFAULT_CAN_ACTIVATE_PUSH;
  basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL;

  basesink->sync = DEFAULT_SYNC;
  basesink->max_lateness = DEFAULT_MAX_LATENESS;
  g_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS);
  priv->async_enabled = DEFAULT_ASYNC;
  priv->ts_offset = DEFAULT_TS_OFFSET;
  priv->render_delay = DEFAULT_RENDER_DELAY;
  priv->blocksize = DEFAULT_BLOCKSIZE;
  priv->cached_clock_id = NULL;
  g_atomic_int_set (&priv->enable_last_sample, DEFAULT_ENABLE_LAST_SAMPLE);
  priv->throttle_time = DEFAULT_THROTTLE_TIME;

  GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_FLAG_SINK);
}

static void
gst_base_sink_finalize (GObject * object)
{
  GstBaseSink *basesink;

  basesink = GST_BASE_SINK (object);

  g_mutex_clear (&basesink->preroll_lock);
  g_cond_clear (&basesink->preroll_cond);

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

/**
 * gst_base_sink_set_sync:
 * @sink: the sink
 * @sync: the new sync value.
 *
 * Configures @sink to synchronize on the clock or not. When
 * @sync is FALSE, incoming samples will be played as fast as
 * possible. If @sync is TRUE, the timestamps of the incomming
 * buffers will be used to schedule the exact render time of its
 * contents.
 */
void
gst_base_sink_set_sync (GstBaseSink * sink, gboolean sync)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->sync = sync;
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_base_sink_get_sync:
 * @sink: the sink
 *
 * Checks if @sink is currently configured to synchronize against the
 * clock.
 *
 * Returns: TRUE if the sink is configured to synchronize against the clock.
 */
gboolean
gst_base_sink_get_sync (GstBaseSink * sink)
{
  gboolean res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), FALSE);

  GST_OBJECT_LOCK (sink);
  res = sink->sync;
  GST_OBJECT_UNLOCK (sink);

  return res;
}

/**
 * gst_base_sink_set_max_lateness:
 * @sink: the sink
 * @max_lateness: the new max lateness value.
 *
 * Sets the new max lateness value to @max_lateness. This value is
 * used to decide if a buffer should be dropped or not based on the
 * buffer timestamp and the current clock time. A value of -1 means
 * an unlimited time.
 */
void
gst_base_sink_set_max_lateness (GstBaseSink * sink, gint64 max_lateness)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->max_lateness = max_lateness;
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_base_sink_get_max_lateness:
 * @sink: the sink
 *
 * Gets the max lateness value. See gst_base_sink_set_max_lateness for
 * more details.
 *
 * Returns: The maximum time in nanoseconds that a buffer can be late
 * before it is dropped and not rendered. A value of -1 means an
 * unlimited time.
 */
gint64
gst_base_sink_get_max_lateness (GstBaseSink * sink)
{
  gint64 res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), -1);

  GST_OBJECT_LOCK (sink);
  res = sink->max_lateness;
  GST_OBJECT_UNLOCK (sink);

  return res;
}

/**
 * gst_base_sink_set_qos_enabled:
 * @sink: the sink
 * @enabled: the new qos value.
 *
 * Configures @sink to send Quality-of-Service events upstream.
 */
void
gst_base_sink_set_qos_enabled (GstBaseSink * sink, gboolean enabled)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

  g_atomic_int_set (&sink->priv->qos_enabled, enabled);
}

/**
 * gst_base_sink_is_qos_enabled:
 * @sink: the sink
 *
 * Checks if @sink is currently configured to send Quality-of-Service events
 * upstream.
 *
 * Returns: TRUE if the sink is configured to perform Quality-of-Service.
 */
gboolean
gst_base_sink_is_qos_enabled (GstBaseSink * sink)
{
  gboolean res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), FALSE);

  res = g_atomic_int_get (&sink->priv->qos_enabled);

  return res;
}

/**
 * gst_base_sink_set_async_enabled:
 * @sink: the sink
 * @enabled: the new async value.
 *
 * Configures @sink to perform all state changes asynchronusly. When async is
 * disabled, the sink will immediately go to PAUSED instead of waiting for a
 * preroll buffer. This feature is useful if the sink does not synchronize
 * against the clock or when it is dealing with sparse streams.
 */
void
gst_base_sink_set_async_enabled (GstBaseSink * sink, gboolean enabled)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

  GST_BASE_SINK_PREROLL_LOCK (sink);
  g_atomic_int_set (&sink->priv->async_enabled, enabled);
  GST_LOG_OBJECT (sink, "set async enabled to %d", enabled);
  GST_BASE_SINK_PREROLL_UNLOCK (sink);
}

/**
 * gst_base_sink_is_async_enabled:
 * @sink: the sink
 *
 * Checks if @sink is currently configured to perform asynchronous state
 * changes to PAUSED.
 *
 * Returns: TRUE if the sink is configured to perform asynchronous state
 * changes.
 */
gboolean
gst_base_sink_is_async_enabled (GstBaseSink * sink)
{
  gboolean res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), FALSE);

  res = g_atomic_int_get (&sink->priv->async_enabled);

  return res;
}

/**
 * gst_base_sink_set_ts_offset:
 * @sink: the sink
 * @offset: the new offset
 *
 * Adjust the synchronisation of @sink with @offset. A negative value will
 * render buffers earlier than their timestamp. A positive value will delay
 * rendering. This function can be used to fix playback of badly timestamped
 * buffers.
 */
void
gst_base_sink_set_ts_offset (GstBaseSink * sink, GstClockTimeDiff offset)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->priv->ts_offset = offset;
  GST_LOG_OBJECT (sink, "set time offset to %" G_GINT64_FORMAT, offset);
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_base_sink_get_ts_offset:
 * @sink: the sink
 *
 * Get the synchronisation offset of @sink.
 *
 * Returns: The synchronisation offset.
 */
GstClockTimeDiff
gst_base_sink_get_ts_offset (GstBaseSink * sink)
{
  GstClockTimeDiff res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), 0);

  GST_OBJECT_LOCK (sink);
  res = sink->priv->ts_offset;
  GST_OBJECT_UNLOCK (sink);

  return res;
}

/**
 * gst_base_sink_get_last_sample:
 * @sink: the sink
 *
 * Get the last sample that arrived in the sink and was used for preroll or for
 * rendering. This property can be used to generate thumbnails.
 *
 * The #GstCaps on the sample can be used to determine the type of the buffer.
 *
 * Free-function: gst_sample_unref
 *
 * Returns: (transfer full): a #GstSample. gst_sample_unref() after usage.
 *     This function returns NULL when no buffer has arrived in the sink yet
 *     or when the sink is not in PAUSED or PLAYING.
 */
GstSample *
gst_base_sink_get_last_sample (GstBaseSink * sink)
{
  GstSample *res = NULL;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), NULL);

  GST_OBJECT_LOCK (sink);
  if (sink->priv->last_buffer) {
    res = gst_sample_new (sink->priv->last_buffer,
        sink->priv->last_caps, &sink->segment, NULL);
  }
  GST_OBJECT_UNLOCK (sink);

  return res;
}

/* with OBJECT_LOCK */
static void
gst_base_sink_set_last_buffer_unlocked (GstBaseSink * sink, GstBuffer * buffer)
{
  GstBuffer *old;

  old = sink->priv->last_buffer;
  if (G_LIKELY (old != buffer)) {
    GST_DEBUG_OBJECT (sink, "setting last buffer to %p", buffer);
    if (G_LIKELY (buffer))
      gst_buffer_ref (buffer);
    sink->priv->last_buffer = buffer;
    if (buffer)
      /* copy over the caps */
      gst_caps_replace (&sink->priv->last_caps, sink->priv->caps);
    else
      gst_caps_replace (&sink->priv->last_caps, NULL);
  } else {
    old = NULL;
  }
  /* avoid unreffing with the lock because cleanup code might want to take the
   * lock too */
  if (G_LIKELY (old)) {
    GST_OBJECT_UNLOCK (sink);
    gst_buffer_unref (old);
    GST_OBJECT_LOCK (sink);
  }
}

static void
gst_base_sink_set_last_buffer (GstBaseSink * sink, GstBuffer * buffer)
{
  if (!g_atomic_int_get (&sink->priv->enable_last_sample))
    return;

  GST_OBJECT_LOCK (sink);
  gst_base_sink_set_last_buffer_unlocked (sink, buffer);
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_base_sink_set_last_sample_enabled:
 * @sink: the sink
 * @enabled: the new enable-last-sample value.
 *
 * Configures @sink to store the last received sample in the last-sample
 * property.
 */
void
gst_base_sink_set_last_sample_enabled (GstBaseSink * sink, gboolean enabled)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

  /* Only take lock if we change the value */
  if (g_atomic_int_compare_and_exchange (&sink->priv->enable_last_sample,
          !enabled, enabled) && !enabled) {
    GST_OBJECT_LOCK (sink);
    gst_base_sink_set_last_buffer_unlocked (sink, NULL);
    GST_OBJECT_UNLOCK (sink);
  }
}

/**
 * gst_base_sink_is_last_sample_enabled:
 * @sink: the sink
 *
 * Checks if @sink is currently configured to store the last received sample in
 * the last-sample property.
 *
 * Returns: TRUE if the sink is configured to store the last received sample.
 */
gboolean
gst_base_sink_is_last_sample_enabled (GstBaseSink * sink)
{
  g_return_val_if_fail (GST_IS_BASE_SINK (sink), FALSE);

  return g_atomic_int_get (&sink->priv->enable_last_sample);
}

/**
 * gst_base_sink_get_latency:
 * @sink: the sink
 *
 * Get the currently configured latency.
 *
 * Returns: The configured latency.
 */
GstClockTime
gst_base_sink_get_latency (GstBaseSink * sink)
{
  GstClockTime res;

  GST_OBJECT_LOCK (sink);
  res = sink->priv->latency;
  GST_OBJECT_UNLOCK (sink);

  return res;
}

/**
 * gst_base_sink_query_latency:
 * @sink: the sink
 * @live: (out) (allow-none): if the sink is live
 * @upstream_live: (out) (allow-none): if an upstream element is live
 * @min_latency: (out) (allow-none): the min latency of the upstream elements
 * @max_latency: (out) (allow-none): the max latency of the upstream elements
 *
 * Query the sink for the latency parameters. The latency will be queried from
 * the upstream elements. @live will be TRUE if @sink is configured to
 * synchronize against the clock. @upstream_live will be TRUE if an upstream
 * element is live.
 *
 * If both @live and @upstream_live are TRUE, the sink will want to compensate
 * for the latency introduced by the upstream elements by setting the
 * @min_latency to a strictly possitive value.
 *
 * This function is mostly used by subclasses.
 *
 * Returns: TRUE if the query succeeded.
 */
gboolean
gst_base_sink_query_latency (GstBaseSink * sink, gboolean * live,
    gboolean * upstream_live, GstClockTime * min_latency,
    GstClockTime * max_latency)
{
  gboolean l, us_live, res, have_latency;
  GstClockTime min, max, render_delay;
  GstQuery *query;
  GstClockTime us_min, us_max;

  /* we are live when we sync to the clock */
  GST_OBJECT_LOCK (sink);
  l = sink->sync;
  have_latency = sink->priv->have_latency;
  render_delay = sink->priv->render_delay;
  GST_OBJECT_UNLOCK (sink);

  /* assume no latency */
  min = 0;
  max = -1;
  us_live = FALSE;

  if (have_latency) {
    GST_DEBUG_OBJECT (sink, "we are ready for LATENCY query");
    /* we are ready for a latency query this is when we preroll or when we are
     * not async. */
    query = gst_query_new_latency ();

    /* ask the peer for the latency */
    if ((res = gst_pad_peer_query (sink->sinkpad, query))) {
      /* get upstream min and max latency */
      gst_query_parse_latency (query, &us_live, &us_min, &us_max);

      if (us_live) {
        /* upstream live, use its latency, subclasses should use these
         * values to create the complete latency. */
        min = us_min;
        max = us_max;
      }
      if (l) {
        /* we need to add the render delay if we are live */
        if (min != -1)
          min += render_delay;
        if (max != -1)
          max += render_delay;
      }
    }
    gst_query_unref (query);
  } else {
    GST_DEBUG_OBJECT (sink, "we are not yet ready for LATENCY query");
    res = FALSE;
  }

  /* not live, we tried to do the query, if it failed we return TRUE anyway */
  if (!res) {
    if (!l) {
      res = TRUE;
      GST_DEBUG_OBJECT (sink, "latency query failed but we are not live");
    } else {
      GST_DEBUG_OBJECT (sink, "latency query failed and we are live");
    }
  }

  if (res) {
    GST_DEBUG_OBJECT (sink, "latency query: live: %d, have_latency %d,"
        " upstream: %d, min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT, l,
        have_latency, us_live, GST_TIME_ARGS (min), GST_TIME_ARGS (max));

    if (live)
      *live = l;
    if (upstream_live)
      *upstream_live = us_live;
    if (min_latency)
      *min_latency = min;
    if (max_latency)
      *max_latency = max;
  }
  return res;
}

/**
 * gst_base_sink_set_render_delay:
 * @sink: a #GstBaseSink
 * @delay: the new delay
 *
 * Set the render delay in @sink to @delay. The render delay is the time
 * between actual rendering of a buffer and its synchronisation time. Some
 * devices might delay media rendering which can be compensated for with this
 * function.
 *
 * After calling this function, this sink will report additional latency and
 * other sinks will adjust their latency to delay the rendering of their media.
 *
 * This function is usually called by subclasses.
 */
void
gst_base_sink_set_render_delay (GstBaseSink * sink, GstClockTime delay)
{
  GstClockTime old_render_delay;

  g_return_if_fail (GST_IS_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  old_render_delay = sink->priv->render_delay;
  sink->priv->render_delay = delay;
  GST_LOG_OBJECT (sink, "set render delay to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (delay));
  GST_OBJECT_UNLOCK (sink);

  if (delay != old_render_delay) {
    GST_DEBUG_OBJECT (sink, "posting latency changed");
    gst_element_post_message (GST_ELEMENT_CAST (sink),
        gst_message_new_latency (GST_OBJECT_CAST (sink)));
  }
}

/**
 * gst_base_sink_get_render_delay:
 * @sink: a #GstBaseSink
 *
 * Get the render delay of @sink. see gst_base_sink_set_render_delay() for more
 * information about the render delay.
 *
 * Returns: the render delay of @sink.
 */
GstClockTime
gst_base_sink_get_render_delay (GstBaseSink * sink)
{
  GstClockTimeDiff res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), 0);

  GST_OBJECT_LOCK (sink);
  res = sink->priv->render_delay;
  GST_OBJECT_UNLOCK (sink);

  return res;
}

/**
 * gst_base_sink_set_blocksize:
 * @sink: a #GstBaseSink
 * @blocksize: the blocksize in bytes
 *
 * Set the number of bytes that the sink will pull when it is operating in pull
 * mode.
 */
/* FIXME 0.11: blocksize property should be int, otherwise min>max.. */
void
gst_base_sink_set_blocksize (GstBaseSink * sink, guint blocksize)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->priv->blocksize = blocksize;
  GST_LOG_OBJECT (sink, "set blocksize to %u", blocksize);
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_base_sink_get_blocksize:
 * @sink: a #GstBaseSink
 *
 * Get the number of bytes that the sink will pull when it is operating in pull
 * mode.
 *
 * Returns: the number of bytes @sink will pull in pull mode.
 */
/* FIXME 0.11: blocksize property should be int, otherwise min>max.. */
guint
gst_base_sink_get_blocksize (GstBaseSink * sink)
{
  guint res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), 0);

  GST_OBJECT_LOCK (sink);
  res = sink->priv->blocksize;
  GST_OBJECT_UNLOCK (sink);

  return res;
}

/**
 * gst_base_sink_set_throttle_time:
 * @sink: a #GstBaseSink
 * @throttle: the throttle time in nanoseconds
 *
 * Set the time that will be inserted between rendered buffers. This
 * can be used to control the maximum buffers per second that the sink
 * will render. 
 */
void
gst_base_sink_set_throttle_time (GstBaseSink * sink, guint64 throttle)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->priv->throttle_time = throttle;
  GST_LOG_OBJECT (sink, "set throttle_time to %" G_GUINT64_FORMAT, throttle);
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_base_sink_get_throttle_time:
 * @sink: a #GstBaseSink
 *
 * Get the time that will be inserted between frames to control the 
 * maximum buffers per second.
 *
 * Returns: the number of nanoseconds @sink will put between frames.
 */
guint64
gst_base_sink_get_throttle_time (GstBaseSink * sink)
{
  guint64 res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), 0);

  GST_OBJECT_LOCK (sink);
  res = sink->priv->throttle_time;
  GST_OBJECT_UNLOCK (sink);

  return res;
}

static void
gst_base_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstBaseSink *sink = GST_BASE_SINK (object);

  switch (prop_id) {
    case PROP_SYNC:
      gst_base_sink_set_sync (sink, g_value_get_boolean (value));
      break;
    case PROP_MAX_LATENESS:
      gst_base_sink_set_max_lateness (sink, g_value_get_int64 (value));
      break;
    case PROP_QOS:
      gst_base_sink_set_qos_enabled (sink, g_value_get_boolean (value));
      break;
    case PROP_ASYNC:
      gst_base_sink_set_async_enabled (sink, g_value_get_boolean (value));
      break;
    case PROP_TS_OFFSET:
      gst_base_sink_set_ts_offset (sink, g_value_get_int64 (value));
      break;
    case PROP_BLOCKSIZE:
      gst_base_sink_set_blocksize (sink, g_value_get_uint (value));
      break;
    case PROP_RENDER_DELAY:
      gst_base_sink_set_render_delay (sink, g_value_get_uint64 (value));
      break;
    case PROP_ENABLE_LAST_SAMPLE:
      gst_base_sink_set_last_sample_enabled (sink, g_value_get_boolean (value));
      break;
    case PROP_THROTTLE_TIME:
      gst_base_sink_set_throttle_time (sink, g_value_get_uint64 (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstBaseSink *sink = GST_BASE_SINK (object);

  switch (prop_id) {
    case PROP_SYNC:
      g_value_set_boolean (value, gst_base_sink_get_sync (sink));
      break;
    case PROP_MAX_LATENESS:
      g_value_set_int64 (value, gst_base_sink_get_max_lateness (sink));
      break;
    case PROP_QOS:
      g_value_set_boolean (value, gst_base_sink_is_qos_enabled (sink));
      break;
    case PROP_ASYNC:
      g_value_set_boolean (value, gst_base_sink_is_async_enabled (sink));
      break;
    case PROP_TS_OFFSET:
      g_value_set_int64 (value, gst_base_sink_get_ts_offset (sink));
      break;
    case PROP_LAST_SAMPLE:
      gst_value_take_buffer (value, gst_base_sink_get_last_sample (sink));
      break;
    case PROP_ENABLE_LAST_SAMPLE:
      g_value_set_boolean (value, gst_base_sink_is_last_sample_enabled (sink));
      break;
    case PROP_BLOCKSIZE:
      g_value_set_uint (value, gst_base_sink_get_blocksize (sink));
      break;
    case PROP_RENDER_DELAY:
      g_value_set_uint64 (value, gst_base_sink_get_render_delay (sink));
      break;
    case PROP_THROTTLE_TIME:
      g_value_set_uint64 (value, gst_base_sink_get_throttle_time (sink));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static GstCaps *
gst_base_sink_default_get_caps (GstBaseSink * sink, GstCaps * filter)
{
  return NULL;
}

static gboolean
gst_base_sink_default_set_caps (GstBaseSink * sink, GstCaps * caps)
{
  return TRUE;
}

/* with PREROLL_LOCK, STREAM_LOCK */
static gboolean
gst_base_sink_commit_state (GstBaseSink * basesink)
{
  /* commit state and proceed to next pending state */
  GstState current, next, pending, post_pending;
  gboolean post_paused = FALSE;
  gboolean post_async_done = FALSE;
  gboolean post_playing = FALSE;

  /* we are certainly not playing async anymore now */
  basesink->playing_async = FALSE;

  GST_OBJECT_LOCK (basesink);
  current = GST_STATE (basesink);
  next = GST_STATE_NEXT (basesink);
  pending = GST_STATE_PENDING (basesink);
  post_pending = pending;

  switch (pending) {
    case GST_STATE_PLAYING:
    {
      GST_DEBUG_OBJECT (basesink, "commiting state to PLAYING");

      basesink->need_preroll = FALSE;
      post_async_done = TRUE;
      basesink->priv->commited = TRUE;
      post_playing = TRUE;
      /* post PAUSED too when we were READY */
      if (current == GST_STATE_READY) {
        post_paused = TRUE;
      }
      break;
    }
    case GST_STATE_PAUSED:
      GST_DEBUG_OBJECT (basesink, "commiting state to PAUSED");
      post_paused = TRUE;
      post_async_done = TRUE;
      basesink->priv->commited = TRUE;
      post_pending = GST_STATE_VOID_PENDING;
      break;
    case GST_STATE_READY:
    case GST_STATE_NULL:
      goto stopping;
    case GST_STATE_VOID_PENDING:
      goto nothing_pending;
    default:
      break;
  }

  /* we can report latency queries now */
  basesink->priv->have_latency = TRUE;

  GST_STATE (basesink) = pending;
  GST_STATE_NEXT (basesink) = GST_STATE_VOID_PENDING;
  GST_STATE_PENDING (basesink) = GST_STATE_VOID_PENDING;
  GST_STATE_RETURN (basesink) = GST_STATE_CHANGE_SUCCESS;
  GST_OBJECT_UNLOCK (basesink);

  if (post_paused) {
    GST_DEBUG_OBJECT (basesink, "posting PAUSED state change message");
    gst_element_post_message (GST_ELEMENT_CAST (basesink),
        gst_message_new_state_changed (GST_OBJECT_CAST (basesink),
            current, next, post_pending));
  }
  if (post_async_done) {
    GST_DEBUG_OBJECT (basesink, "posting async-done message");
    gst_element_post_message (GST_ELEMENT_CAST (basesink),
        gst_message_new_async_done (GST_OBJECT_CAST (basesink),
            GST_CLOCK_TIME_NONE));
  }
  if (post_playing) {
    GST_DEBUG_OBJECT (basesink, "posting PLAYING state change message");
    gst_element_post_message (GST_ELEMENT_CAST (basesink),
        gst_message_new_state_changed (GST_OBJECT_CAST (basesink),
            next, pending, GST_STATE_VOID_PENDING));
  }

  GST_STATE_BROADCAST (basesink);

  return TRUE;

nothing_pending:
  {
    /* Depending on the state, set our vars. We get in this situation when the
     * state change function got a change to update the state vars before the
     * streaming thread did. This is fine but we need to make sure that we
     * update the need_preroll var since it was TRUE when we got here and might
     * become FALSE if we got to PLAYING. */
    GST_DEBUG_OBJECT (basesink, "nothing to commit, now in %s",
        gst_element_state_get_name (current));
    switch (current) {
      case GST_STATE_PLAYING:
        basesink->need_preroll = FALSE;
        break;
      case GST_STATE_PAUSED:
        basesink->need_preroll = TRUE;
        break;
      default:
        basesink->need_preroll = FALSE;
        basesink->flushing = TRUE;
        break;
    }
    /* we can report latency queries now */
    basesink->priv->have_latency = TRUE;
    GST_OBJECT_UNLOCK (basesink);
    return TRUE;
  }
stopping:
  {
    /* app is going to READY */
    GST_DEBUG_OBJECT (basesink, "stopping");
    basesink->need_preroll = FALSE;
    basesink->flushing = TRUE;
    GST_OBJECT_UNLOCK (basesink);
    return FALSE;
  }
}

static void
start_stepping (GstBaseSink * sink, GstSegment * segment,
    GstStepInfo * pending, GstStepInfo * current)
{
  gint64 end;
  GstMessage *message;

  GST_DEBUG_OBJECT (sink, "update pending step");

  GST_OBJECT_LOCK (sink);
  memcpy (current, pending, sizeof (GstStepInfo));
  pending->valid = FALSE;
  GST_OBJECT_UNLOCK (sink);

  /* post message first */
  message =
      gst_message_new_step_start (GST_OBJECT (sink), TRUE, current->format,
      current->amount, current->rate, current->flush, current->intermediate);
  gst_message_set_seqnum (message, current->seqnum);
  gst_element_post_message (GST_ELEMENT (sink), message);

  /* get the running time of where we paused and remember it */
  current->start = gst_element_get_start_time (GST_ELEMENT_CAST (sink));
  gst_segment_set_running_time (segment, GST_FORMAT_TIME, current->start);

  /* set the new rate for the remainder of the segment */
  current->start_rate = segment->rate;
  segment->rate *= current->rate;

  /* save values */
  if (segment->rate > 0.0)
    current->start_stop = segment->stop;
  else
    current->start_start = segment->start;

  if (current->format == GST_FORMAT_TIME) {
    /* calculate the running-time when the step operation should stop */
    if (current->amount != -1)
      end = current->start + current->amount;
    else
      end = -1;

    if (!current->flush) {
      gint64 position;

      /* update the segment clipping regions for non-flushing seeks */
      if (segment->rate > 0.0) {
        if (end != -1)
          position = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
        else
          position = segment->stop;

        segment->stop = position;
        segment->position = position;
      } else {
        if (end != -1)
          position = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
        else
          position = segment->start;

        segment->time = position;
        segment->start = position;
        segment->position = position;
      }
    }
  }

  GST_DEBUG_OBJECT (sink, "segment now %" GST_SEGMENT_FORMAT, segment);
  GST_DEBUG_OBJECT (sink, "step started at running_time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (current->start));

  GST_DEBUG_OBJECT (sink, "step amount: %" G_GUINT64_FORMAT ", format: %s, "
      "rate: %f", current->amount, gst_format_get_name (current->format),
      current->rate);
}

static void
stop_stepping (GstBaseSink * sink, GstSegment * segment,
    GstStepInfo * current, gint64 rstart, gint64 rstop, gboolean eos)
{
  gint64 stop, position;
  GstMessage *message;

  GST_DEBUG_OBJECT (sink, "step complete");

  if (segment->rate > 0.0)
    stop = rstart;
  else
    stop = rstop;

  GST_DEBUG_OBJECT (sink,
      "step stop at running_time %" GST_TIME_FORMAT, GST_TIME_ARGS (stop));

  if (stop == -1)
    current->duration = current->position;
  else
    current->duration = stop - current->start;

  GST_DEBUG_OBJECT (sink, "step elapsed running_time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (current->duration));

  position = current->start + current->duration;

  /* now move the segment to the new running time */
  gst_segment_set_running_time (segment, GST_FORMAT_TIME, position);

  if (current->flush) {
    /* and remove the time we flushed, start time did not change */
    segment->base = current->start;
  } else {
    /* start time is now the stepped position */
    gst_element_set_start_time (GST_ELEMENT_CAST (sink), position);
  }

  /* restore the previous rate */
  segment->rate = current->start_rate;

  if (segment->rate > 0.0)
    segment->stop = current->start_stop;
  else
    segment->start = current->start_start;

  /* post the step done when we know the stepped duration in TIME */
  message =
      gst_message_new_step_done (GST_OBJECT_CAST (sink), current->format,
      current->amount, current->rate, current->flush, current->intermediate,
      current->duration, eos);
  gst_message_set_seqnum (message, current->seqnum);
  gst_element_post_message (GST_ELEMENT_CAST (sink), message);

  if (!current->intermediate)
    sink->need_preroll = current->need_preroll;

  /* and the current step info finished and becomes invalid */
  current->valid = FALSE;
}

static gboolean
handle_stepping (GstBaseSink * sink, GstSegment * segment,
    GstStepInfo * current, guint64 * cstart, guint64 * cstop, guint64 * rstart,
    guint64 * rstop)
{
  gboolean step_end = FALSE;

  /* stepping never stops */
  if (current->amount == -1)
    return FALSE;

  /* see if we need to skip this buffer because of stepping */
  switch (current->format) {
    case GST_FORMAT_TIME:
    {
      guint64 end;
      guint64 first, last;
      gdouble abs_rate;

      if (segment->rate > 0.0) {
        if (segment->stop == *cstop)
          *rstop = *rstart + current->amount;

        first = *rstart;
        last = *rstop;
      } else {
        if (segment->start == *cstart)
          *rstart = *rstop + current->amount;

        first = *rstop;
        last = *rstart;
      }

      end = current->start + current->amount;
      current->position = first - current->start;

      abs_rate = ABS (segment->rate);
      if (G_UNLIKELY (abs_rate != 1.0))
        current->position /= abs_rate;

      GST_DEBUG_OBJECT (sink,
          "buffer: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
          GST_TIME_ARGS (first), GST_TIME_ARGS (last));
      GST_DEBUG_OBJECT (sink,
          "got time step %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT "/%"
          GST_TIME_FORMAT, GST_TIME_ARGS (current->position),
          GST_TIME_ARGS (last - current->start),
          GST_TIME_ARGS (current->amount));

      if ((current->flush && current->position >= current->amount)
          || last >= end) {
        GST_DEBUG_OBJECT (sink, "step ended, we need clipping");
        step_end = TRUE;
        if (segment->rate > 0.0) {
          *rstart = end;
          *cstart = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
        } else {
          *rstop = end;
          *cstop = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
        }
      }
      GST_DEBUG_OBJECT (sink,
          "cstart %" GST_TIME_FORMAT ", rstart %" GST_TIME_FORMAT,
          GST_TIME_ARGS (*cstart), GST_TIME_ARGS (*rstart));
      GST_DEBUG_OBJECT (sink,
          "cstop %" GST_TIME_FORMAT ", rstop %" GST_TIME_FORMAT,
          GST_TIME_ARGS (*cstop), GST_TIME_ARGS (*rstop));
      break;
    }
    case GST_FORMAT_BUFFERS:
      GST_DEBUG_OBJECT (sink,
          "got default step %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT,
          current->position, current->amount);

      if (current->position < current->amount) {
        current->position++;
      } else {
        step_end = TRUE;
      }
      break;
    case GST_FORMAT_DEFAULT:
    default:
      GST_DEBUG_OBJECT (sink,
          "got unknown step %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT,
          current->position, current->amount);
      break;
  }
  return step_end;
}

/* with STREAM_LOCK, PREROLL_LOCK
 *
 * Returns TRUE if the object needs synchronisation and takes therefore
 * part in prerolling.
 *
 * rsstart/rsstop contain the start/stop in stream time.
 * rrstart/rrstop contain the start/stop in running time.
 */
static gboolean
gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj,
    GstClockTime * rsstart, GstClockTime * rsstop,
    GstClockTime * rrstart, GstClockTime * rrstop, gboolean * do_sync,
    gboolean * stepped, GstStepInfo * step, gboolean * step_end)
{
  GstBaseSinkClass *bclass;
  GstClockTime start, stop;     /* raw start/stop timestamps */
  guint64 cstart, cstop;        /* clipped raw timestamps */
  guint64 rstart, rstop;        /* clipped timestamps converted to running time */
  GstClockTime sstart, sstop;   /* clipped timestamps converted to stream time */
  GstFormat format;
  GstBaseSinkPrivate *priv;
  GstSegment *segment;
  gboolean eos;

  priv = basesink->priv;
  segment = &basesink->segment;

  bclass = GST_BASE_SINK_GET_CLASS (basesink);

again:
  /* start with nothing */
  start = stop = GST_CLOCK_TIME_NONE;
  eos = FALSE;

  if (G_UNLIKELY (GST_IS_EVENT (obj))) {
    GstEvent *event = GST_EVENT_CAST (obj);

    switch (GST_EVENT_TYPE (event)) {
        /* EOS event needs syncing */
      case GST_EVENT_EOS:
      {
        if (segment->rate >= 0.0) {
          sstart = sstop = priv->current_sstop;
          if (!GST_CLOCK_TIME_IS_VALID (sstart)) {
            /* we have not seen a buffer yet, use the segment values */
            sstart = sstop = gst_segment_to_stream_time (segment,
                segment->format, segment->stop);
          }
        } else {
          sstart = sstop = priv->current_sstart;
          if (!GST_CLOCK_TIME_IS_VALID (sstart)) {
            /* we have not seen a buffer yet, use the segment values */
            sstart = sstop = gst_segment_to_stream_time (segment,
                segment->format, segment->start);
          }
        }

        rstart = rstop = priv->eos_rtime;
        *do_sync = rstart != -1;
        GST_DEBUG_OBJECT (basesink, "sync times for EOS %" GST_TIME_FORMAT,
            GST_TIME_ARGS (rstart));
        /* if we are stepping, we end now */
        *step_end = step->valid;
        eos = TRUE;
        goto eos_done;
      }
      case GST_EVENT_GAP:
      {
        GstClockTime timestamp, duration;
        gst_event_parse_gap (event, &timestamp, &duration);

        GST_DEBUG_OBJECT (basesink, "Got Gap time %" GST_TIME_FORMAT
            " duration %" GST_TIME_FORMAT,
            GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));

        if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
          start = timestamp;
          if (GST_CLOCK_TIME_IS_VALID (duration))
            stop = start + duration;
        }
        *do_sync = TRUE;
        break;
      }
      default:
        /* other events do not need syncing */
        return FALSE;
    }
  } else {
    /* else do buffer sync code */
    GstBuffer *buffer = GST_BUFFER_CAST (obj);

    /* just get the times to see if we need syncing, if the start returns -1 we
     * don't sync. */
    if (bclass->get_times)
      bclass->get_times (basesink, buffer, &start, &stop);

    if (!GST_CLOCK_TIME_IS_VALID (start)) {
      /* we don't need to sync but we still want to get the timestamps for
       * tracking the position */
      gst_base_sink_default_get_times (basesink, buffer, &start, &stop);
      *do_sync = FALSE;
    } else {
      *do_sync = TRUE;
    }
  }

  GST_DEBUG_OBJECT (basesink, "got times start: %" GST_TIME_FORMAT
      ", stop: %" GST_TIME_FORMAT ", do_sync %d", GST_TIME_ARGS (start),
      GST_TIME_ARGS (stop), *do_sync);

  /* collect segment and format for code clarity */
  format = segment->format;

  /* clip */
  if (G_UNLIKELY (!gst_segment_clip (segment, format,
              start, stop, &cstart, &cstop))) {
    if (step->valid) {
      GST_DEBUG_OBJECT (basesink, "step out of segment");
      /* when we are stepping, pretend we're at the end of the segment */
      if (segment->rate > 0.0) {
        cstart = segment->stop;
        cstop = segment->stop;
      } else {
        cstart = segment->start;
        cstop = segment->start;
      }
      goto do_times;
    }
    goto out_of_segment;
  }

  if (G_UNLIKELY (start != cstart || stop != cstop)) {
    GST_DEBUG_OBJECT (basesink, "clipped to: start %" GST_TIME_FORMAT
        ", stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (cstart),
        GST_TIME_ARGS (cstop));
  }

  /* set last stop position */
  if (G_LIKELY (stop != GST_CLOCK_TIME_NONE && cstop != GST_CLOCK_TIME_NONE))
    segment->position = cstop;
  else
    segment->position = cstart;

do_times:
  rstart = gst_segment_to_running_time (segment, format, cstart);
  rstop = gst_segment_to_running_time (segment, format, cstop);

  if (G_UNLIKELY (step->valid)) {
    if (!(*step_end = handle_stepping (basesink, segment, step, &cstart, &cstop,
                &rstart, &rstop))) {
      /* step is still busy, we discard data when we are flushing */
      *stepped = step->flush;
      GST_DEBUG_OBJECT (basesink, "stepping busy");
    }
  }
  /* this can produce wrong values if we accumulated non-TIME segments. If this happens,
   * upstream is behaving very badly */
  sstart = gst_segment_to_stream_time (segment, format, cstart);
  sstop = gst_segment_to_stream_time (segment, format, cstop);

eos_done:
  /* eos_done label only called when doing EOS, we also stop stepping then */
  if (*step_end && step->flush) {
    GST_DEBUG_OBJECT (basesink, "flushing step ended");
    stop_stepping (basesink, segment, step, rstart, rstop, eos);
    *step_end = FALSE;
    /* re-determine running start times for adjusted segment
     * (which has a flushed amount of running/accumulated time removed) */
    if (!GST_IS_EVENT (obj)) {
      GST_DEBUG_OBJECT (basesink, "refresh sync times");
      goto again;
    }
  }

  /* save times */
  *rsstart = sstart;
  *rsstop = sstop;
  *rrstart = rstart;
  *rrstop = rstop;

  /* buffers and EOS always need syncing and preroll */
  return TRUE;

  /* special cases */
out_of_segment:
  {
    /* we usually clip in the chain function already but stepping could cause
     * the segment to be updated later. we return FALSE so that we don't try
     * to sync on it. */
    GST_LOG_OBJECT (basesink, "buffer skipped, not in segment");
    return FALSE;
  }
}

/* with STREAM_LOCK, PREROLL_LOCK, LOCK
 * adjust a timestamp with the latency and timestamp offset. This function does
 * not adjust for the render delay. */
static GstClockTime
gst_base_sink_adjust_time (GstBaseSink * basesink, GstClockTime time)
{
  GstClockTimeDiff ts_offset;

  /* don't do anything funny with invalid timestamps */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time)))
    return time;

  time += basesink->priv->latency;

  /* apply offset, be carefull for underflows */
  ts_offset = basesink->priv->ts_offset;
  if (ts_offset < 0) {
    ts_offset = -ts_offset;
    if (ts_offset < time)
      time -= ts_offset;
    else
      time = 0;
  } else
    time += ts_offset;

  /* subtract the render delay again, which was included in the latency */
  if (time > basesink->priv->render_delay)
    time -= basesink->priv->render_delay;
  else
    time = 0;

  return time;
}

/**
 * gst_base_sink_wait_clock:
 * @sink: the sink
 * @time: the running_time to be reached
 * @jitter: (out) (allow-none): the jitter to be filled with time diff, or NULL
 *
 * This function will block until @time is reached. It is usually called by
 * subclasses that use their own internal synchronisation.
 *
 * If @time is not valid, no sycnhronisation is done and #GST_CLOCK_BADTIME is
 * returned. Likewise, if synchronisation is disabled in the element or there
 * is no clock, no synchronisation is done and #GST_CLOCK_BADTIME is returned.
 *
 * This function should only be called with the PREROLL_LOCK held, like when
 * receiving an EOS event in the #GstBaseSinkClass.event() vmethod or when
 * receiving a buffer in
 * the #GstBaseSinkClass.render() vmethod.
 *
 * The @time argument should be the running_time of when this method should
 * return and is not adjusted with any latency or offset configured in the
 * sink.
 *
 * Returns: #GstClockReturn
 */
GstClockReturn
gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
    GstClockTimeDiff * jitter)
{
  GstClockReturn ret;
  GstClock *clock;
  GstClockTime base_time;

  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time)))
    goto invalid_time;

  GST_OBJECT_LOCK (sink);
  if (G_UNLIKELY (!sink->sync))
    goto no_sync;

  if (G_UNLIKELY ((clock = GST_ELEMENT_CLOCK (sink)) == NULL))
    goto no_clock;

  base_time = GST_ELEMENT_CAST (sink)->base_time;
  GST_LOG_OBJECT (sink,
      "time %" GST_TIME_FORMAT ", base_time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (time), GST_TIME_ARGS (base_time));

  /* add base_time to running_time to get the time against the clock */
  time += base_time;

  /* Re-use existing clockid if available */
  /* FIXME: Casting to GstClockEntry only works because the types
   * are the same */
  if (G_LIKELY (sink->priv->cached_clock_id != NULL
          && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv->
              cached_clock_id) == clock)) {
    if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id,
            time)) {
      gst_clock_id_unref (sink->priv->cached_clock_id);
      sink->priv->cached_clock_id = gst_clock_new_single_shot_id (clock, time);
    }
  } else {
    if (sink->priv->cached_clock_id != NULL)
      gst_clock_id_unref (sink->priv->cached_clock_id);
    sink->priv->cached_clock_id = gst_clock_new_single_shot_id (clock, time);
  }
  GST_OBJECT_UNLOCK (sink);

  /* A blocking wait is performed on the clock. We save the ClockID
   * so we can unlock the entry at any time. While we are blocking, we
   * release the PREROLL_LOCK so that other threads can interrupt the
   * entry. */
  sink->clock_id = sink->priv->cached_clock_id;
  /* release the preroll lock while waiting */
  GST_BASE_SINK_PREROLL_UNLOCK (sink);

  ret = gst_clock_id_wait (sink->priv->cached_clock_id, jitter);

  GST_BASE_SINK_PREROLL_LOCK (sink);
  sink->clock_id = NULL;

  return ret;

  /* no syncing needed */
invalid_time:
  {
    GST_DEBUG_OBJECT (sink, "time not valid, no sync needed");
    return GST_CLOCK_BADTIME;
  }
no_sync:
  {
    GST_DEBUG_OBJECT (sink, "sync disabled");
    GST_OBJECT_UNLOCK (sink);
    return GST_CLOCK_BADTIME;
  }
no_clock:
  {
    GST_DEBUG_OBJECT (sink, "no clock, can't sync");
    GST_OBJECT_UNLOCK (sink);
    return GST_CLOCK_BADTIME;
  }
}

/**
 * gst_base_sink_wait_preroll:
 * @sink: the sink
 *
 * If the #GstBaseSinkClass.render() method performs its own synchronisation
 * against the clock it must unblock when going from PLAYING to the PAUSED state
 * and call this method before continuing to render the remaining data.
 *
 * This function will block until a state change to PLAYING happens (in which
 * case this function returns #GST_FLOW_OK) or the processing must be stopped due
 * to a state change to READY or a FLUSH event (in which case this function
 * returns #GST_FLOW_FLUSHING).
 *
 * This function should only be called with the PREROLL_LOCK held, like in the
 * render function.
 *
 * Returns: #GST_FLOW_OK if the preroll completed and processing can
 * continue. Any other return value should be returned from the render vmethod.
 */
GstFlowReturn
gst_base_sink_wait_preroll (GstBaseSink * sink)
{
  sink->have_preroll = TRUE;
  GST_DEBUG_OBJECT (sink, "waiting in preroll for flush or PLAYING");
  /* block until the state changes, or we get a flush, or something */
  GST_BASE_SINK_PREROLL_WAIT (sink);
  sink->have_preroll = FALSE;
  if (G_UNLIKELY (sink->flushing))
    goto stopping;
  if (G_UNLIKELY (sink->priv->step_unlock))
    goto step_unlocked;
  GST_DEBUG_OBJECT (sink, "continue after preroll");

  return GST_FLOW_OK;

  /* ERRORS */
stopping:
  {
    GST_DEBUG_OBJECT (sink, "preroll interrupted because of flush");
    return GST_FLOW_FLUSHING;
  }
step_unlocked:
  {
    sink->priv->step_unlock = FALSE;
    GST_DEBUG_OBJECT (sink, "preroll interrupted because of step");
    return GST_FLOW_STEP;
  }
}

/**
 * gst_base_sink_do_preroll:
 * @sink: the sink
 * @obj: (transfer none): the mini object that caused the preroll
 *
 * If the @sink spawns its own thread for pulling buffers from upstream it
 * should call this method after it has pulled a buffer. If the element needed
 * to preroll, this function will perform the preroll and will then block
 * until the element state is changed.
 *
 * This function should be called with the PREROLL_LOCK held.
 *
 * Returns: #GST_FLOW_OK if the preroll completed and processing can
 * continue. Any other return value should be returned from the render vmethod.
 */
GstFlowReturn
gst_base_sink_do_preroll (GstBaseSink * sink, GstMiniObject * obj)
{
  GstFlowReturn ret;

  while (G_UNLIKELY (sink->need_preroll)) {
    GST_DEBUG_OBJECT (sink, "prerolling object %p", obj);

    /* if it's a buffer, we need to call the preroll method */
    if (sink->priv->call_preroll) {
      GstBaseSinkClass *bclass;
      GstBuffer *buf;

      if (GST_IS_BUFFER_LIST (obj)) {
        buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
        g_assert (NULL != buf);
      } else if (GST_IS_BUFFER (obj)) {
        buf = GST_BUFFER_CAST (obj);
        /* For buffer lists do not set last buffer for now */
        gst_base_sink_set_last_buffer (sink, buf);
      } else
        buf = NULL;

      if (buf) {
        GST_DEBUG_OBJECT (sink, "preroll buffer %" GST_TIME_FORMAT,
            GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));

        bclass = GST_BASE_SINK_GET_CLASS (sink);

        if (bclass->prepare)
          if ((ret = bclass->prepare (sink, buf)) != GST_FLOW_OK)
            goto prepare_canceled;

        if (bclass->preroll)
          if ((ret = bclass->preroll (sink, buf)) != GST_FLOW_OK)
            goto preroll_canceled;

        sink->priv->call_preroll = FALSE;
      }
    }

    /* commit state */
    if (G_LIKELY (sink->playing_async)) {
      if (G_UNLIKELY (!gst_base_sink_commit_state (sink)))
        goto stopping;
    }

    /* need to recheck here because the commit state could have
     * made us not need the preroll anymore */
    if (G_LIKELY (sink->need_preroll)) {
      /* block until the state changes, or we get a flush, or something */
      ret = gst_base_sink_wait_preroll (sink);
      if ((ret != GST_FLOW_OK) && (ret != GST_FLOW_STEP))
        goto preroll_failed;
    }
  }
  return GST_FLOW_OK;

  /* ERRORS */
prepare_canceled:
  {
    GST_DEBUG_OBJECT (sink, "prepare failed, abort state");
    gst_element_abort_state (GST_ELEMENT_CAST (sink));
    return ret;
  }
preroll_canceled:
  {
    GST_DEBUG_OBJECT (sink, "preroll failed, abort state");
    gst_element_abort_state (GST_ELEMENT_CAST (sink));
    return ret;
  }
stopping:
  {
    GST_DEBUG_OBJECT (sink, "stopping while commiting state");
    return GST_FLOW_FLUSHING;
  }
preroll_failed:
  {
    GST_DEBUG_OBJECT (sink, "preroll failed: %s", gst_flow_get_name (ret));
    return ret;
  }
}

/**
 * gst_base_sink_wait:
 * @sink: the sink
 * @time: the running_time to be reached
 * @jitter: (out) (allow-none): the jitter to be filled with time diff, or NULL
 *
 * This function will wait for preroll to complete and will then block until @time
 * is reached. It is usually called by subclasses that use their own internal
 * synchronisation but want to let some synchronization (like EOS) be handled
 * by the base class.
 *
 * This function should only be called with the PREROLL_LOCK held (like when
 * receiving an EOS event in the ::event vmethod or when handling buffers in
 * ::render).
 *
 * The @time argument should be the running_time of when the timeout should happen
 * and will be adjusted with any latency and offset configured in the sink.
 *
 * Returns: #GstFlowReturn
 */
GstFlowReturn
gst_base_sink_wait (GstBaseSink * sink, GstClockTime time,
    GstClockTimeDiff * jitter)
{
  GstClockReturn status;
  GstFlowReturn ret;

  do {
    GstClockTime stime;

    GST_DEBUG_OBJECT (sink, "checking preroll");

    /* first wait for the playing state before we can continue */
    while (G_UNLIKELY (sink->need_preroll)) {
      ret = gst_base_sink_wait_preroll (sink);
      if ((ret != GST_FLOW_OK) && (ret != GST_FLOW_STEP))
        goto flushing;
    }

    /* preroll done, we can sync since we are in PLAYING now. */
    GST_DEBUG_OBJECT (sink, "possibly waiting for clock to reach %"
        GST_TIME_FORMAT, GST_TIME_ARGS (time));

    /* compensate for latency, ts_offset and render delay */
    stime = gst_base_sink_adjust_time (sink, time);

    /* wait for the clock, this can be interrupted because we got shut down or
     * we PAUSED. */
    status = gst_base_sink_wait_clock (sink, stime, jitter);

    GST_DEBUG_OBJECT (sink, "clock returned %d", status);

    /* invalid time, no clock or sync disabled, just continue then */
    if (status == GST_CLOCK_BADTIME)
      break;

    /* waiting could have been interrupted and we can be flushing now */
    if (G_UNLIKELY (sink->flushing))
      goto flushing;

    /* retry if we got unscheduled, which means we did not reach the timeout
     * yet. if some other error occures, we continue. */
  } while (status == GST_CLOCK_UNSCHEDULED);

  GST_DEBUG_OBJECT (sink, "end of stream");

  return GST_FLOW_OK;

  /* ERRORS */
flushing:
  {
    GST_DEBUG_OBJECT (sink, "we are flushing");
    return GST_FLOW_FLUSHING;
  }
}

/* with STREAM_LOCK, PREROLL_LOCK
 *
 * Make sure we are in PLAYING and synchronize an object to the clock.
 *
 * If we need preroll, we are not in PLAYING. We try to commit the state
 * if needed and then block if we still are not PLAYING.
 *
 * We start waiting on the clock in PLAYING. If we got interrupted, we
 * immediately try to re-preroll.
 *
 * Some objects do not need synchronisation (most events) and so this function
 * immediately returns GST_FLOW_OK.
 *
 * for objects that arrive later than max-lateness to be synchronized to the
 * clock have the @late boolean set to TRUE.
 *
 * This function keeps a running average of the jitter (the diff between the
 * clock time and the requested sync time). The jitter is negative for
 * objects that arrive in time and positive for late buffers.
 *
 * does not take ownership of obj.
 */
static GstFlowReturn
gst_base_sink_do_sync (GstBaseSink * basesink,
    GstMiniObject * obj, gboolean * late, gboolean * step_end)
{
  GstClockTimeDiff jitter = 0;
  gboolean syncable;
  GstClockReturn status = GST_CLOCK_OK;
  GstClockTime rstart, rstop, sstart, sstop, stime;
  gboolean do_sync;
  GstBaseSinkPrivate *priv;
  GstFlowReturn ret;
  GstStepInfo *current, *pending;
  gboolean stepped;

  priv = basesink->priv;

do_step:
  sstart = sstop = rstart = rstop = GST_CLOCK_TIME_NONE;
  do_sync = TRUE;
  stepped = FALSE;

  priv->current_rstart = GST_CLOCK_TIME_NONE;

  /* get stepping info */
  current = &priv->current_step;
  pending = &priv->pending_step;

  /* get timing information for this object against the render segment */
  syncable = gst_base_sink_get_sync_times (basesink, obj,
      &sstart, &sstop, &rstart, &rstop, &do_sync, &stepped, current, step_end);

  if (G_UNLIKELY (stepped))
    goto step_skipped;

  /* a syncable object needs to participate in preroll and
   * clocking. All buffers and EOS are syncable. */
  if (G_UNLIKELY (!syncable))
    goto not_syncable;

  /* store timing info for current object */
  priv->current_rstart = rstart;
  priv->current_rstop = (GST_CLOCK_TIME_IS_VALID (rstop) ? rstop : rstart);

  /* save sync time for eos when the previous object needed sync */
  priv->eos_rtime = (do_sync ? priv->current_rstop : GST_CLOCK_TIME_NONE);

  /* calculate inter frame spacing */
  if (G_UNLIKELY (priv->prev_rstart != -1 && priv->prev_rstart < rstart)) {
    GstClockTime in_diff;

    in_diff = rstart - priv->prev_rstart;

    if (priv->avg_in_diff == -1)
      priv->avg_in_diff = in_diff;
    else
      priv->avg_in_diff = UPDATE_RUNNING_AVG (priv->avg_in_diff, in_diff);

    GST_LOG_OBJECT (basesink, "avg frame diff %" GST_TIME_FORMAT,
        GST_TIME_ARGS (priv->avg_in_diff));

  }
  priv->prev_rstart = rstart;

  if (G_UNLIKELY (priv->earliest_in_time != -1
          && rstart < priv->earliest_in_time))
    goto qos_dropped;

again:
  /* first do preroll, this makes sure we commit our state
   * to PAUSED and can continue to PLAYING. We cannot perform
   * any clock sync in PAUSED because there is no clock. */
  ret = gst_base_sink_do_preroll (basesink, obj);
  if (G_UNLIKELY (ret != GST_FLOW_OK))
    goto preroll_failed;

  /* update the segment with a pending step if the current one is invalid and we
   * have a new pending one. We only accept new step updates after a preroll */
  if (G_UNLIKELY (pending->valid && !current->valid)) {
    start_stepping (basesink, &basesink->segment, pending, current);
    goto do_step;
  }

  /* After rendering we store the position of the last buffer so that we can use
   * it to report the position. We need to take the lock here. */
  GST_OBJECT_LOCK (basesink);
  priv->current_sstart = sstart;
  priv->current_sstop = (GST_CLOCK_TIME_IS_VALID (sstop) ? sstop : sstart);
  GST_OBJECT_UNLOCK (basesink);

  if (!do_sync)
    goto done;

  /* adjust for latency */
  stime = gst_base_sink_adjust_time (basesink, rstart);

  /* preroll done, we can sync since we are in PLAYING now. */
  GST_DEBUG_OBJECT (basesink, "possibly waiting for clock to reach %"
      GST_TIME_FORMAT ", adjusted %" GST_TIME_FORMAT,
      GST_TIME_ARGS (rstart), GST_TIME_ARGS (stime));

  /* This function will return immediately if start == -1, no clock
   * or sync is disabled with GST_CLOCK_BADTIME. */
  status = gst_base_sink_wait_clock (basesink, stime, &jitter);

  GST_DEBUG_OBJECT (basesink, "clock returned %d, jitter %c%" GST_TIME_FORMAT,
      status, (jitter < 0 ? '-' : ' '), GST_TIME_ARGS (ABS (jitter)));

  /* invalid time, no clock or sync disabled, just render */
  if (status == GST_CLOCK_BADTIME)
    goto done;

  /* waiting could have been interrupted and we can be flushing now */
  if (G_UNLIKELY (basesink->flushing))
    goto flushing;

  /* check for unlocked by a state change, we are not flushing so
   * we can try to preroll on the current buffer. */
  if (G_UNLIKELY (status == GST_CLOCK_UNSCHEDULED)) {
    GST_DEBUG_OBJECT (basesink, "unscheduled, waiting some more");
    priv->call_preroll = TRUE;
    goto again;
  }

  /* successful syncing done, record observation */
  priv->current_jitter = jitter;

  /* check if the object should be dropped */
  *late = gst_base_sink_is_too_late (basesink, obj, rstart, rstop,
      status, jitter);

done:
  return GST_FLOW_OK;

  /* ERRORS */
step_skipped:
  {
    GST_DEBUG_OBJECT (basesink, "skipped stepped object %p", obj);
    *late = TRUE;
    return GST_FLOW_OK;
  }
not_syncable:
  {
    GST_DEBUG_OBJECT (basesink, "non syncable object %p", obj);
    return GST_FLOW_OK;
  }
qos_dropped:
  {
    GST_DEBUG_OBJECT (basesink, "dropped because of QoS %p", obj);
    *late = TRUE;
    return GST_FLOW_OK;
  }
flushing:
  {
    GST_DEBUG_OBJECT (basesink, "we are flushing");
    return GST_FLOW_FLUSHING;
  }
preroll_failed:
  {
    GST_DEBUG_OBJECT (basesink, "preroll failed");
    *step_end = FALSE;
    return ret;
  }
}

static gboolean
gst_base_sink_send_qos (GstBaseSink * basesink, GstQOSType type,
    gdouble proportion, GstClockTime time, GstClockTimeDiff diff)
{
  GstEvent *event;
  gboolean res;

  /* generate Quality-of-Service event */
  GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink,
      "qos: type %d, proportion: %lf, diff %" G_GINT64_FORMAT ", timestamp %"
      GST_TIME_FORMAT, type, proportion, diff, GST_TIME_ARGS (time));

  event = gst_event_new_qos (type, proportion, diff, time);

  /* send upstream */
  res = gst_pad_push_event (basesink->sinkpad, event);

  return res;
}

static void
gst_base_sink_perform_qos (GstBaseSink * sink, gboolean dropped)
{
  GstBaseSinkPrivate *priv;
  GstClockTime start, stop;
  GstClockTimeDiff jitter;
  GstClockTime pt, entered, left;
  GstClockTime duration;
  gdouble rate;

  priv = sink->priv;

  start = priv->current_rstart;

  if (priv->current_step.valid)
    return;

  /* if Quality-of-Service disabled, do nothing */
  if (!g_atomic_int_get (&priv->qos_enabled) ||
      !GST_CLOCK_TIME_IS_VALID (start))
    return;

  stop = priv->current_rstop;
  jitter = priv->current_jitter;

  if (jitter < 0) {
    /* this is the time the buffer entered the sink */
    if (start < -jitter)
      entered = 0;
    else
      entered = start + jitter;
    left = start;
  } else {
    /* this is the time the buffer entered the sink */
    entered = start + jitter;
    /* this is the time the buffer left the sink */
    left = start + jitter;
  }

  /* calculate duration of the buffer */
  if (GST_CLOCK_TIME_IS_VALID (stop) && stop != start)
    duration = stop - start;
  else
    duration = priv->avg_in_diff;

  /* if we have the time when the last buffer left us, calculate
   * processing time */
  if (GST_CLOCK_TIME_IS_VALID (priv->last_left)) {
    if (entered > priv->last_left) {
      pt = entered - priv->last_left;
    } else {
      pt = 0;
    }
  } else {
    pt = priv->avg_pt;
  }

  GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, "start: %" GST_TIME_FORMAT
      ", stop %" GST_TIME_FORMAT ", entered %" GST_TIME_FORMAT ", left %"
      GST_TIME_FORMAT ", pt: %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
      ",jitter %" G_GINT64_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
      GST_TIME_ARGS (entered), GST_TIME_ARGS (left), GST_TIME_ARGS (pt),
      GST_TIME_ARGS (duration), jitter);

  GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, "avg_duration: %" GST_TIME_FORMAT
      ", avg_pt: %" GST_TIME_FORMAT ", avg_rate: %g",
      GST_TIME_ARGS (priv->avg_duration), GST_TIME_ARGS (priv->avg_pt),
      priv->avg_rate);

  /* collect running averages. for first observations, we copy the
   * values */
  if (!GST_CLOCK_TIME_IS_VALID (priv->avg_duration))
    priv->avg_duration = duration;
  else
    priv->avg_duration = UPDATE_RUNNING_AVG (priv->avg_duration, duration);

  if (!GST_CLOCK_TIME_IS_VALID (priv->avg_pt))
    priv->avg_pt = pt;
  else
    priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt);

  if (priv->avg_duration != 0)
    rate =
        gst_guint64_to_gdouble (priv->avg_pt) /
        gst_guint64_to_gdouble (priv->avg_duration);
  else
    rate = 1.0;

  if (GST_CLOCK_TIME_IS_VALID (priv->last_left)) {
    if (dropped || priv->avg_rate < 0.0) {
      priv->avg_rate = rate;
    } else {
      if (rate > 1.0)
        priv->avg_rate = UPDATE_RUNNING_AVG_N (priv->avg_rate, rate);
      else
        priv->avg_rate = UPDATE_RUNNING_AVG_P (priv->avg_rate, rate);
    }
  }

  GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink,
      "updated: avg_duration: %" GST_TIME_FORMAT ", avg_pt: %" GST_TIME_FORMAT
      ", avg_rate: %g", GST_TIME_ARGS (priv->avg_duration),
      GST_TIME_ARGS (priv->avg_pt), priv->avg_rate);


  if (priv->avg_rate >= 0.0) {
    GstQOSType type;
    GstClockTimeDiff diff;

    /* if we have a valid rate, start sending QoS messages */
    if (priv->current_jitter < 0) {
      /* make sure we never go below 0 when adding the jitter to the
       * timestamp. */
      if (priv->current_rstart < -priv->current_jitter)
        priv->current_jitter = -priv->current_rstart;
    }

    if (priv->throttle_time > 0) {
      diff = priv->throttle_time;
      type = GST_QOS_TYPE_THROTTLE;
    } else {
      diff = priv->current_jitter;
      if (diff <= 0)
        type = GST_QOS_TYPE_OVERFLOW;
      else
        type = GST_QOS_TYPE_UNDERFLOW;
    }

    gst_base_sink_send_qos (sink, type, priv->avg_rate, priv->current_rstart,
        diff);
  }

  /* record when this buffer will leave us */
  priv->last_left = left;
}

/* reset all qos measuring */
static void
gst_base_sink_reset_qos (GstBaseSink * sink)
{
  GstBaseSinkPrivate *priv;

  priv = sink->priv;

  priv->last_render_time = GST_CLOCK_TIME_NONE;
  priv->prev_rstart = GST_CLOCK_TIME_NONE;
  priv->earliest_in_time = GST_CLOCK_TIME_NONE;
  priv->last_left = GST_CLOCK_TIME_NONE;
  priv->avg_duration = GST_CLOCK_TIME_NONE;
  priv->avg_pt = GST_CLOCK_TIME_NONE;
  priv->avg_rate = -1.0;
  priv->avg_render = GST_CLOCK_TIME_NONE;
  priv->avg_in_diff = GST_CLOCK_TIME_NONE;
  priv->rendered = 0;
  priv->dropped = 0;

}

/* Checks if the object was scheduled too late.
 *
 * rstart/rstop contain the running_time start and stop values
 * of the object.
 *
 * status and jitter contain the return values from the clock wait.
 *
 * returns TRUE if the buffer was too late.
 */
static gboolean
gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
    GstClockTime rstart, GstClockTime rstop,
    GstClockReturn status, GstClockTimeDiff jitter)
{
  gboolean late;
  guint64 max_lateness;
  GstBaseSinkPrivate *priv;

  priv = basesink->priv;

  late = FALSE;

  /* only for objects that were too late */
  if (G_LIKELY (status != GST_CLOCK_EARLY))
    goto in_time;

  max_lateness = basesink->max_lateness;

  /* check if frame dropping is enabled */
  if (max_lateness == -1)
    goto no_drop;

  /* only check for buffers */
  if (G_UNLIKELY (!GST_IS_BUFFER (obj)))
    goto not_buffer;

  /* can't do check if we don't have a timestamp */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (rstart)))
    goto no_timestamp;

  /* we can add a valid stop time */
  if (GST_CLOCK_TIME_IS_VALID (rstop))
    max_lateness += rstop;
  else {
    max_lateness += rstart;
    /* no stop time, use avg frame diff */
    if (priv->avg_in_diff != -1)
      max_lateness += priv->avg_in_diff;
  }

  /* if the jitter bigger than duration and lateness we are too late */
  if ((late = rstart + jitter > max_lateness)) {
    GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, basesink,
        "buffer is too late %" GST_TIME_FORMAT
        " > %" GST_TIME_FORMAT, GST_TIME_ARGS (rstart + jitter),
        GST_TIME_ARGS (max_lateness));
    /* !!emergency!!, if we did not receive anything valid for more than a
     * second, render it anyway so the user sees something */
    if (GST_CLOCK_TIME_IS_VALID (priv->last_render_time) &&
        rstart - priv->last_render_time > GST_SECOND) {
      late = FALSE;
      GST_ELEMENT_WARNING (basesink, CORE, CLOCK,
          (_("A lot of buffers are being dropped.")),
          ("There may be a timestamping problem, or this computer is too slow."));
      GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, basesink,
          "**emergency** last buffer at %" GST_TIME_FORMAT " > GST_SECOND",
          GST_TIME_ARGS (priv->last_render_time));
    }
  }

done:
  if (!late || !GST_CLOCK_TIME_IS_VALID (priv->last_render_time)) {
    priv->last_render_time = rstart;
    /* the next allowed input timestamp */
    if (priv->throttle_time > 0)
      priv->earliest_in_time = rstart + priv->throttle_time;
  }
  return late;

  /* all is fine */
in_time:
  {
    GST_DEBUG_OBJECT (basesink, "object was scheduled in time");
    goto done;
  }
no_drop:
  {
    GST_DEBUG_OBJECT (basesink, "frame dropping disabled");
    goto done;
  }
not_buffer:
  {
    GST_DEBUG_OBJECT (basesink, "object is not a buffer");
    return FALSE;
  }
no_timestamp:
  {
    GST_DEBUG_OBJECT (basesink, "buffer has no timestamp");
    return FALSE;
  }
}

/* called before and after calling the render vmethod. It keeps track of how
 * much time was spent in the render method and is used to check if we are
 * flooded */
static void
gst_base_sink_do_render_stats (GstBaseSink * basesink, gboolean start)
{
  GstBaseSinkPrivate *priv;

  priv = basesink->priv;

  if (start) {
    priv->start = gst_util_get_timestamp ();
  } else {
    GstClockTime elapsed;

    priv->stop = gst_util_get_timestamp ();

    elapsed = GST_CLOCK_DIFF (priv->start, priv->stop);

    if (!GST_CLOCK_TIME_IS_VALID (priv->avg_render))
      priv->avg_render = elapsed;
    else
      priv->avg_render = UPDATE_RUNNING_AVG (priv->avg_render, elapsed);

    GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink,
        "avg_render: %" GST_TIME_FORMAT, GST_TIME_ARGS (priv->avg_render));
  }
}

static void
gst_base_sink_flush_start (GstBaseSink * basesink, GstPad * pad)
{
  /* make sure we are not blocked on the clock also clear any pending
   * eos state. */
  gst_base_sink_set_flushing (basesink, pad, TRUE);

  /* we grab the stream lock but that is not needed since setting the
   * sink to flushing would make sure no state commit is being done
   * anymore */
  GST_PAD_STREAM_LOCK (pad);
  gst_base_sink_reset_qos (basesink);
  /* and we need to commit our state again on the next
   * prerolled buffer */
  basesink->playing_async = TRUE;
  if (basesink->priv->async_enabled) {
    gst_element_lost_state (GST_ELEMENT_CAST (basesink));
  } else {
    /* start time reset in above case as well;
     * arranges for a.o. proper position reporting when flushing in PAUSED */
    gst_element_set_start_time (GST_ELEMENT_CAST (basesink), 0);
    basesink->priv->have_latency = TRUE;
  }
  gst_base_sink_set_last_buffer (basesink, NULL);
  GST_PAD_STREAM_UNLOCK (pad);
}

static void
gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad,
    gboolean reset_time)
{
  /* unset flushing so we can accept new data, this also flushes out any EOS
   * event. */
  gst_base_sink_set_flushing (basesink, pad, FALSE);

  /* for position reporting */
  GST_OBJECT_LOCK (basesink);
  basesink->priv->current_sstart = GST_CLOCK_TIME_NONE;
  basesink->priv->current_sstop = GST_CLOCK_TIME_NONE;
  basesink->priv->eos_rtime = GST_CLOCK_TIME_NONE;
  basesink->priv->call_preroll = TRUE;
  basesink->priv->current_step.valid = FALSE;
  basesink->priv->pending_step.valid = FALSE;
  if (basesink->pad_mode == GST_PAD_MODE_PUSH) {
    /* we need new segment info after the flush. */
    basesink->have_newsegment = FALSE;
    if (reset_time) {
      gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
    }
  }
  GST_OBJECT_UNLOCK (basesink);

  if (reset_time) {
    GST_DEBUG_OBJECT (basesink, "posting reset-time message");
    gst_element_post_message (GST_ELEMENT_CAST (basesink),
        gst_message_new_reset_time (GST_OBJECT_CAST (basesink), 0));
  }
}

static GstFlowReturn
gst_base_sink_default_wait_event (GstBaseSink * basesink, GstEvent * event)
{
  GstFlowReturn ret;
  gboolean late, step_end;

  ret = gst_base_sink_do_sync (basesink, GST_MINI_OBJECT_CAST (event),
      &late, &step_end);

  return ret;
}

static GstFlowReturn
gst_base_sink_wait_event (GstBaseSink * basesink, GstEvent * event)
{
  GstFlowReturn ret;
  GstBaseSinkClass *bclass;

  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  if (G_LIKELY (bclass->wait_event))
    ret = bclass->wait_event (basesink, event);
  else
    ret = GST_FLOW_NOT_SUPPORTED;

  return ret;
}

static gboolean
gst_base_sink_default_event (GstBaseSink * basesink, GstEvent * event)
{
  gboolean result = TRUE;
  GstBaseSinkClass *bclass;

  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
    {
      GST_DEBUG_OBJECT (basesink, "flush-start %p", event);
      gst_base_sink_flush_start (basesink, basesink->sinkpad);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
    {
      gboolean reset_time;

      gst_event_parse_flush_stop (event, &reset_time);
      GST_DEBUG_OBJECT (basesink, "flush-stop %p, reset_time: %d", event,
          reset_time);
      gst_base_sink_flush_stop (basesink, basesink->sinkpad, reset_time);
      break;
    }
    case GST_EVENT_EOS:
    {
      GstMessage *message;
      guint32 seqnum;

      /* we set the received EOS flag here so that we can use it when testing if
       * we are prerolled and to refuse more buffers. */
      basesink->priv->received_eos = TRUE;

      /* wait for EOS */
      if (G_UNLIKELY (gst_base_sink_wait_event (basesink,
                  event) != GST_FLOW_OK)) {
        result = FALSE;
        goto done;
      }

      /* the EOS event is completely handled so we mark
       * ourselves as being in the EOS state. eos is also
       * protected by the object lock so we can read it when
       * answering the POSITION query. */
      GST_OBJECT_LOCK (basesink);
      basesink->eos = TRUE;
      GST_OBJECT_UNLOCK (basesink);

      /* ok, now we can post the message */
      GST_DEBUG_OBJECT (basesink, "Now posting EOS");

      seqnum = basesink->priv->seqnum = gst_event_get_seqnum (event);
      GST_DEBUG_OBJECT (basesink, "Got seqnum #%" G_GUINT32_FORMAT, seqnum);

      message = gst_message_new_eos (GST_OBJECT_CAST (basesink));
      gst_message_set_seqnum (message, seqnum);
      gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
      break;
    }
    case GST_EVENT_STREAM_START:
    {
      GstMessage *message;
      guint32 seqnum;

      seqnum = gst_event_get_seqnum (event);
      GST_DEBUG_OBJECT (basesink, "Now posting STREAM_START (seqnum:%d)",
          seqnum);
      message = gst_message_new_stream_start (GST_OBJECT_CAST (basesink));
      gst_message_set_seqnum (message, seqnum);
      gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
      break;
    }
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      GST_DEBUG_OBJECT (basesink, "caps %p", event);

      gst_event_parse_caps (event, &caps);
      if (bclass->set_caps)
        result = bclass->set_caps (basesink, caps);

      if (result) {
        GST_OBJECT_LOCK (basesink);
        gst_caps_replace (&basesink->priv->caps, caps);
        GST_OBJECT_UNLOCK (basesink);
      }
      break;
    }
    case GST_EVENT_SEGMENT:
      /* configure the segment */
      /* The segment is protected with both the STREAM_LOCK and the OBJECT_LOCK.
       * We protect with the OBJECT_LOCK so that we can use the values to
       * safely answer a POSITION query. */
      GST_OBJECT_LOCK (basesink);
      /* the newsegment event is needed to bring the buffer timestamps to the
       * stream time and to drop samples outside of the playback segment. */
      gst_event_copy_segment (event, &basesink->segment);
      GST_DEBUG_OBJECT (basesink, "configured SEGMENT %" GST_SEGMENT_FORMAT,
          &basesink->segment);
      basesink->have_newsegment = TRUE;
      GST_OBJECT_UNLOCK (basesink);
      break;
    case GST_EVENT_GAP:
    {
      if (G_UNLIKELY (gst_base_sink_wait_event (basesink,
                  event) != GST_FLOW_OK))
        result = FALSE;
      break;
    }
    case GST_EVENT_TAG:
    {
      GstTagList *taglist;

      gst_event_parse_tag (event, &taglist);

      gst_element_post_message (GST_ELEMENT_CAST (basesink),
          gst_message_new_tag (GST_OBJECT_CAST (basesink),
              gst_tag_list_copy (taglist)));
      break;
    }
    case GST_EVENT_TOC:
    {
      GstToc *toc;
      gboolean updated;

      gst_event_parse_toc (event, &toc, &updated);

      gst_element_post_message (GST_ELEMENT_CAST (basesink),
          gst_message_new_toc (GST_OBJECT_CAST (basesink), toc, updated));

      gst_toc_unref (toc);
      break;
    }
    case GST_EVENT_SINK_MESSAGE:
    {
      GstMessage *msg = NULL;

      gst_event_parse_sink_message (event, &msg);
      if (msg)
        gst_element_post_message (GST_ELEMENT_CAST (basesink), msg);
      break;
    }
    default:
      break;
  }
done:
  gst_event_unref (event);

  return result;
}

static gboolean
gst_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstBaseSink *basesink;
  gboolean result = TRUE;
  GstBaseSinkClass *bclass;

  basesink = GST_BASE_SINK_CAST (parent);
  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  GST_DEBUG_OBJECT (basesink, "received event %p %" GST_PTR_FORMAT, event,
      event);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      /* special case for this serialized event because we don't want to grab
       * the PREROLL lock or check if we were flushing */
      if (bclass->event)
        result = bclass->event (basesink, event);
      break;
    default:
      if (GST_EVENT_IS_SERIALIZED (event)) {
        GST_BASE_SINK_PREROLL_LOCK (basesink);
        if (G_UNLIKELY (basesink->flushing))
          goto flushing;

        if (G_UNLIKELY (basesink->priv->received_eos))
          goto after_eos;

        if (bclass->event)
          result = bclass->event (basesink, event);

        GST_BASE_SINK_PREROLL_UNLOCK (basesink);
      } else {
        if (bclass->event)
          result = bclass->event (basesink, event);
      }
      break;
  }
done:
  return result;

  /* ERRORS */
flushing:
  {
    GST_DEBUG_OBJECT (basesink, "we are flushing");
    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
    gst_event_unref (event);
    result = FALSE;
    goto done;
  }

after_eos:
  {
    GST_DEBUG_OBJECT (basesink, "Event received after EOS, dropping");
    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
    gst_event_unref (event);
    result = FALSE;
    goto done;
  }
}

/* default implementation to calculate the start and end
 * timestamps on a buffer, subclasses can override
 */
static void
gst_base_sink_default_get_times (GstBaseSink * basesink, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end)
{
  GstClockTime timestamp, duration;

  /* first sync on DTS, else use PTS */
  timestamp = GST_BUFFER_DTS (buffer);
  if (!GST_CLOCK_TIME_IS_VALID (timestamp))
    timestamp = GST_BUFFER_PTS (buffer);

  if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
    /* get duration to calculate end time */
    duration = GST_BUFFER_DURATION (buffer);
    if (GST_CLOCK_TIME_IS_VALID (duration)) {
      *end = timestamp + duration;
    }
    *start = timestamp;
  }
}

/* must be called with PREROLL_LOCK */
static gboolean
gst_base_sink_needs_preroll (GstBaseSink * basesink)
{
  gboolean is_prerolled, res;

  /* we have 2 cases where the PREROLL_LOCK is released:
   *  1) we are blocking in the PREROLL_LOCK and thus are prerolled.
   *  2) we are syncing on the clock
   */
  is_prerolled = basesink->have_preroll || basesink->priv->received_eos;
  res = !is_prerolled;

  GST_DEBUG_OBJECT (basesink, "have_preroll: %d, EOS: %d => needs preroll: %d",
      basesink->have_preroll, basesink->priv->received_eos, res);

  return res;
}

/* with STREAM_LOCK, PREROLL_LOCK
 *
 * Takes a buffer and compare the timestamps with the last segment.
 * If the buffer falls outside of the segment boundaries, drop it.
 * Else send the buffer for preroll and rendering.
 *
 * This function takes ownership of the buffer.
 */
static GstFlowReturn
gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
    gpointer obj, gboolean is_list)
{
  GstBaseSinkClass *bclass;
  GstBaseSinkPrivate *priv = basesink->priv;
  GstFlowReturn ret;
  GstClockTime start = GST_CLOCK_TIME_NONE, end = GST_CLOCK_TIME_NONE;
  GstSegment *segment;
  GstBuffer *sync_buf;
  gint do_qos;
  gboolean late, step_end;

  if (G_UNLIKELY (basesink->flushing))
    goto flushing;

  if (G_UNLIKELY (priv->received_eos))
    goto was_eos;

  if (is_list) {
    sync_buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
    g_assert (NULL != sync_buf);
  } else {
    sync_buf = GST_BUFFER_CAST (obj);
  }

  /* for code clarity */
  segment = &basesink->segment;

  if (G_UNLIKELY (!basesink->have_newsegment)) {
    gboolean sync;

    sync = gst_base_sink_get_sync (basesink);
    if (sync) {
      GST_ELEMENT_WARNING (basesink, STREAM, FAILED,
          (_("Internal data flow problem.")),
          ("Received buffer without a new-segment. Assuming timestamps start from 0."));
    }

    /* this means this sink will assume timestamps start from 0 */
    GST_OBJECT_LOCK (basesink);
    segment->start = 0;
    segment->stop = -1;
    basesink->segment.start = 0;
    basesink->segment.stop = -1;
    basesink->have_newsegment = TRUE;
    GST_OBJECT_UNLOCK (basesink);
  }

  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  /* check if the buffer needs to be dropped, we first ask the subclass for the
   * start and end */
  if (bclass->get_times)
    bclass->get_times (basesink, sync_buf, &start, &end);

  if (!GST_CLOCK_TIME_IS_VALID (start)) {
    /* if the subclass does not want sync, we use our own values so that we at
     * least clip the buffer to the segment */
    gst_base_sink_default_get_times (basesink, sync_buf, &start, &end);
  }

  GST_DEBUG_OBJECT (basesink, "got times start: %" GST_TIME_FORMAT
      ", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));

  /* a dropped buffer does not participate in anything */
  if (GST_CLOCK_TIME_IS_VALID (start) && (segment->format == GST_FORMAT_TIME)) {
    if (G_UNLIKELY (!gst_segment_clip (segment,
                GST_FORMAT_TIME, start, end, NULL, NULL)))
      goto out_of_segment;
  }

  if (!is_list) {
    if (bclass->prepare) {
      ret = bclass->prepare (basesink, GST_BUFFER_CAST (obj));
      if (G_UNLIKELY (ret != GST_FLOW_OK))
        goto prepare_failed;
    }
  } else {
    if (bclass->prepare_list) {
      ret = bclass->prepare_list (basesink, GST_BUFFER_LIST_CAST (obj));
      if (G_UNLIKELY (ret != GST_FLOW_OK))
        goto prepare_failed;
    }
  }

again:
  late = FALSE;
  step_end = FALSE;

  /* synchronize this object, non syncable objects return OK
   * immediately. */
  ret = gst_base_sink_do_sync (basesink, GST_MINI_OBJECT_CAST (sync_buf),
      &late, &step_end);
  if (G_UNLIKELY (ret != GST_FLOW_OK))
    goto sync_failed;

  /* drop late buffers unconditionally, let's hope it's unlikely */
  if (G_UNLIKELY (late))
    goto dropped;

  /* read once, to get same value before and after */
  do_qos = g_atomic_int_get (&priv->qos_enabled);

  GST_DEBUG_OBJECT (basesink, "rendering object %p", obj);

  /* record rendering time for QoS and stats */
  if (do_qos)
    gst_base_sink_do_render_stats (basesink, TRUE);

  if (!is_list) {
    /* For buffer lists do not set last buffer for now. */
    gst_base_sink_set_last_buffer (basesink, GST_BUFFER_CAST (obj));

    if (bclass->render)
      ret = bclass->render (basesink, GST_BUFFER_CAST (obj));
  } else {
    if (bclass->render_list)
      ret = bclass->render_list (basesink, GST_BUFFER_LIST_CAST (obj));
  }

  if (do_qos)
    gst_base_sink_do_render_stats (basesink, FALSE);

  if (ret == GST_FLOW_STEP)
    goto again;

  if (G_UNLIKELY (basesink->flushing))
    goto flushing;

  priv->rendered++;

done:
  if (step_end) {
    /* the step ended, check if we need to activate a new step */
    GST_DEBUG_OBJECT (basesink, "step ended");
    stop_stepping (basesink, &basesink->segment, &priv->current_step,
        priv->current_rstart, priv->current_rstop, basesink->eos);
    goto again;
  }

  gst_base_sink_perform_qos (basesink, late);

  GST_DEBUG_OBJECT (basesink, "object unref after render %p", obj);
  gst_mini_object_unref (GST_MINI_OBJECT_CAST (obj));

  return ret;

  /* ERRORS */
flushing:
  {
    GST_DEBUG_OBJECT (basesink, "sink is flushing");
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (obj));
    return GST_FLOW_FLUSHING;
  }
was_eos:
  {
    GST_DEBUG_OBJECT (basesink, "we are EOS, dropping object, return EOS");
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (obj));
    return GST_FLOW_EOS;
  }
out_of_segment:
  {
    GST_DEBUG_OBJECT (basesink, "dropping buffer, out of clipping segment");
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (obj));
    return GST_FLOW_OK;
  }
prepare_failed:
  {
    GST_DEBUG_OBJECT (basesink, "prepare buffer failed %s",
        gst_flow_get_name (ret));
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (obj));
    return ret;
  }
sync_failed:
  {
    GST_DEBUG_OBJECT (basesink, "do_sync returned %s", gst_flow_get_name (ret));
    goto done;
  }
dropped:
  {
    priv->dropped++;
    GST_DEBUG_OBJECT (basesink, "buffer late, dropping");

    if (g_atomic_int_get (&priv->qos_enabled)) {
      GstMessage *qos_msg;
      GstClockTime timestamp, duration;

      timestamp = GST_BUFFER_TIMESTAMP (GST_BUFFER_CAST (sync_buf));
      duration = GST_BUFFER_DURATION (GST_BUFFER_CAST (sync_buf));

      GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink,
          "qos: dropped buffer rt %" GST_TIME_FORMAT ", st %" GST_TIME_FORMAT
          ", ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT,
          GST_TIME_ARGS (priv->current_rstart),
          GST_TIME_ARGS (priv->current_sstart), GST_TIME_ARGS (timestamp),
          GST_TIME_ARGS (duration));
      GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink,
          "qos: rendered %" G_GUINT64_FORMAT ", dropped %" G_GUINT64_FORMAT,
          priv->rendered, priv->dropped);

      qos_msg =
          gst_message_new_qos (GST_OBJECT_CAST (basesink), basesink->sync,
          priv->current_rstart, priv->current_sstart, timestamp, duration);
      gst_message_set_qos_values (qos_msg, priv->current_jitter, priv->avg_rate,
          1000000);
      gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS, priv->rendered,
          priv->dropped);
      gst_element_post_message (GST_ELEMENT_CAST (basesink), qos_msg);
    }
    goto done;
  }
}

/* with STREAM_LOCK
 */
static GstFlowReturn
gst_base_sink_chain_main (GstBaseSink * basesink, GstPad * pad, gpointer obj,
    gboolean is_list)
{
  GstFlowReturn result;

  if (G_UNLIKELY (basesink->pad_mode != GST_PAD_MODE_PUSH))
    goto wrong_mode;

  GST_BASE_SINK_PREROLL_LOCK (basesink);
  result = gst_base_sink_chain_unlocked (basesink, pad, obj, is_list);
  GST_BASE_SINK_PREROLL_UNLOCK (basesink);

done:
  return result;

  /* ERRORS */
wrong_mode:
  {
    GST_OBJECT_LOCK (pad);
    GST_WARNING_OBJECT (basesink,
        "Push on pad %s:%s, but it was not activated in push mode",
        GST_DEBUG_PAD_NAME (pad));
    GST_OBJECT_UNLOCK (pad);
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (obj));
    /* we don't post an error message this will signal to the peer
     * pushing that EOS is reached. */
    result = GST_FLOW_EOS;
    goto done;
  }
}

static GstFlowReturn
gst_base_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstBaseSink *basesink;

  basesink = GST_BASE_SINK (parent);

  return gst_base_sink_chain_main (basesink, pad, buf, FALSE);
}

static GstFlowReturn
gst_base_sink_chain_list (GstPad * pad, GstObject * parent,
    GstBufferList * list)
{
  GstBaseSink *basesink;
  GstBaseSinkClass *bclass;
  GstFlowReturn result;

  basesink = GST_BASE_SINK (parent);
  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  if (G_LIKELY (bclass->render_list)) {
    result = gst_base_sink_chain_main (basesink, pad, list, TRUE);
  } else {
    guint i, len;
    GstBuffer *buffer;

    GST_INFO_OBJECT (pad, "chaining each buffer in list");

    len = gst_buffer_list_length (list);

    result = GST_FLOW_OK;
    for (i = 0; i < len; i++) {
      buffer = gst_buffer_list_get (list, i);
      result = gst_base_sink_chain_main (basesink, pad,
          gst_buffer_ref (buffer), FALSE);
      if (result != GST_FLOW_OK)
        break;
    }
    gst_buffer_list_unref (list);
  }
  return result;
}


static gboolean
gst_base_sink_default_do_seek (GstBaseSink * sink, GstSegment * segment)
{
  gboolean res = TRUE;

  /* update our offset if the start/stop position was updated */
  if (segment->format == GST_FORMAT_BYTES) {
    segment->time = segment->start;
  } else if (segment->start == 0) {
    /* seek to start, we can implement a default for this. */
    segment->time = 0;
  } else {
    res = FALSE;
    GST_INFO_OBJECT (sink, "Can't do a default seek");
  }

  return res;
}

#define SEEK_TYPE_IS_RELATIVE(t) (((t) != GST_SEEK_TYPE_NONE) && ((t) != GST_SEEK_TYPE_SET))

static gboolean
gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
    GstEvent * event, GstSegment * segment)
{
  /* By default, we try one of 2 things:
   *   - For absolute seek positions, convert the requested position to our
   *     configured processing format and place it in the output segment \
   *   - For relative seek positions, convert our current (input) values to the
   *     seek format, adjust by the relative seek offset and then convert back to
   *     the processing format
   */
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  GstSeekFlags flags;
  GstFormat seek_format;
  gdouble rate;
  gboolean update;
  gboolean res = TRUE;

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

  if (seek_format == segment->format) {
    gst_segment_do_seek (segment, rate, seek_format, flags,
        start_type, start, stop_type, stop, &update);
    return TRUE;
  }

  if (start_type != GST_SEEK_TYPE_NONE) {
    /* FIXME: Handle seek_end by converting the input segment vals */
    res =
        gst_pad_query_convert (sink->sinkpad, seek_format, start,
        segment->format, &start);
    start_type = GST_SEEK_TYPE_SET;
  }

  if (res && stop_type != GST_SEEK_TYPE_NONE) {
    /* FIXME: Handle seek_end by converting the input segment vals */
    res =
        gst_pad_query_convert (sink->sinkpad, seek_format, stop,
        segment->format, &stop);
    stop_type = GST_SEEK_TYPE_SET;
  }

  /* And finally, configure our output segment in the desired format */
  gst_segment_do_seek (segment, rate, segment->format, flags, start_type, start,
      stop_type, stop, &update);

  if (!res)
    goto no_format;

  return res;

no_format:
  {
    GST_DEBUG_OBJECT (sink, "undefined format given, seek aborted.");
    return FALSE;
  }
}

/* perform a seek, only executed in pull mode */
static gboolean
gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
{
  gboolean flush;
  gdouble rate;
  GstFormat seek_format, dest_format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gboolean seekseg_configured = FALSE;
  gint64 start, stop;
  gboolean update, res = TRUE;
  GstSegment seeksegment;

  dest_format = sink->segment.format;

  if (event) {
    GST_DEBUG_OBJECT (sink, "performing seek with event %p", event);
    gst_event_parse_seek (event, &rate, &seek_format, &flags,
        &start_type, &start, &stop_type, &stop);

    flush = flags & GST_SEEK_FLAG_FLUSH;
  } else {
    GST_DEBUG_OBJECT (sink, "performing seek without event");
    flush = FALSE;
  }

  if (flush) {
    GST_DEBUG_OBJECT (sink, "flushing upstream");
    gst_pad_push_event (pad, gst_event_new_flush_start ());
    gst_base_sink_flush_start (sink, pad);
  } else {
    GST_DEBUG_OBJECT (sink, "pausing pulling thread");
  }

  GST_PAD_STREAM_LOCK (pad);

  /* If we configured the seeksegment above, don't overwrite it now. Otherwise
   * copy the current segment info into the temp segment that we can actually
   * attempt the seek with. We only update the real segment if the seek succeeds. */
  if (!seekseg_configured) {
    memcpy (&seeksegment, &sink->segment, sizeof (GstSegment));

    /* now configure the final seek segment */
    if (event) {
      if (sink->segment.format != seek_format) {
        /* OK, here's where we give the subclass a chance to convert the relative
         * seek into an absolute one in the processing format. We set up any
         * absolute seek above, before taking the stream lock. */
        if (!gst_base_sink_default_prepare_seek_segment (sink, event,
                &seeksegment)) {
          GST_DEBUG_OBJECT (sink,
              "Preparing the seek failed after flushing. " "Aborting seek");
          res = FALSE;
        }
      } else {
        /* The seek format matches our processing format, no need to ask the
         * the subclass to configure the segment. */
        gst_segment_do_seek (&seeksegment, rate, seek_format, flags,
            start_type, start, stop_type, stop, &update);
      }
    }
    /* Else, no seek event passed, so we're just (re)starting the
       current segment. */
  }

  if (res) {
    GST_DEBUG_OBJECT (sink, "segment configured from %" G_GINT64_FORMAT
        " to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
        seeksegment.start, seeksegment.stop, seeksegment.position);

    /* do the seek, segment.position contains the new position. */
    res = gst_base_sink_default_do_seek (sink, &seeksegment);
  }


  if (flush) {
    GST_DEBUG_OBJECT (sink, "stop flushing upstream");
    gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
    gst_base_sink_flush_stop (sink, pad, TRUE);
  } else if (res && sink->running) {
    /* we are running the current segment and doing a non-flushing seek,
     * close the segment first based on the position. */
    GST_DEBUG_OBJECT (sink, "closing running segment %" G_GINT64_FORMAT
        " to %" G_GINT64_FORMAT, sink->segment.start, sink->segment.position);
  }

  /* The subclass must have converted the segment to the processing format
   * by now */
  if (res && seeksegment.format != dest_format) {
    GST_DEBUG_OBJECT (sink, "Subclass failed to prepare a seek segment "
        "in the correct format. Aborting seek.");
    res = FALSE;
  }

  /* if successful seek, we update our real segment and push
   * out the new segment. */
  if (res) {
    gst_segment_copy_into (&seeksegment, &sink->segment);

    if (sink->segment.flags & GST_SEGMENT_FLAG_SEGMENT) {
      gst_element_post_message (GST_ELEMENT (sink),
          gst_message_new_segment_start (GST_OBJECT (sink),
              sink->segment.format, sink->segment.position));
    }
  }

  sink->priv->discont = TRUE;
  sink->running = TRUE;

  GST_PAD_STREAM_UNLOCK (pad);

  return res;
}

static void
set_step_info (GstBaseSink * sink, GstStepInfo * current, GstStepInfo * pending,
    guint seqnum, GstFormat format, guint64 amount, gdouble rate,
    gboolean flush, gboolean intermediate)
{
  GST_OBJECT_LOCK (sink);
  pending->seqnum = seqnum;
  pending->format = format;
  pending->amount = amount;
  pending->position = 0;
  pending->rate = rate;
  pending->flush = flush;
  pending->intermediate = intermediate;
  pending->valid = TRUE;
  /* flush invalidates the current stepping segment */
  if (flush)
    current->valid = FALSE;
  GST_OBJECT_UNLOCK (sink);
}

static gboolean
gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
{
  GstBaseSinkPrivate *priv;
  GstBaseSinkClass *bclass;
  gboolean flush, intermediate;
  gdouble rate;
  GstFormat format;
  guint64 amount;
  guint seqnum;
  GstStepInfo *pending, *current;
  GstMessage *message;

  bclass = GST_BASE_SINK_GET_CLASS (sink);
  priv = sink->priv;

  GST_DEBUG_OBJECT (sink, "performing step with event %p", event);

  gst_event_parse_step (event, &format, &amount, &rate, &flush, &intermediate);
  seqnum = gst_event_get_seqnum (event);

  pending = &priv->pending_step;
  current = &priv->current_step;

  /* post message first */
  message = gst_message_new_step_start (GST_OBJECT (sink), FALSE, format,
      amount, rate, flush, intermediate);
  gst_message_set_seqnum (message, seqnum);
  gst_element_post_message (GST_ELEMENT (sink), message);

  if (flush) {
    /* we need to call ::unlock before locking PREROLL_LOCK
     * since we lock it before going into ::render */
    if (bclass->unlock)
      bclass->unlock (sink);

    GST_BASE_SINK_PREROLL_LOCK (sink);
    /* now that we have the PREROLL lock, clear our unlock request */
    if (bclass->unlock_stop)
      bclass->unlock_stop (sink);

    /* update the stepinfo and make it valid */
    set_step_info (sink, current, pending, seqnum, format, amount, rate, flush,
        intermediate);

    if (sink->priv->async_enabled) {
      /* and we need to commit our state again on the next
       * prerolled buffer */
      sink->playing_async = TRUE;
      priv->pending_step.need_preroll = TRUE;
      sink->need_preroll = FALSE;
      gst_element_lost_state (GST_ELEMENT_CAST (sink));
    } else {
      sink->priv->have_latency = TRUE;
      sink->need_preroll = FALSE;
    }
    priv->current_sstart = GST_CLOCK_TIME_NONE;
    priv->current_sstop = GST_CLOCK_TIME_NONE;
    priv->eos_rtime = GST_CLOCK_TIME_NONE;
    priv->call_preroll = TRUE;
    gst_base_sink_set_last_buffer (sink, NULL);
    gst_base_sink_reset_qos (sink);

    if (sink->clock_id) {
      gst_clock_id_unschedule (sink->clock_id);
    }

    if (sink->have_preroll) {
      GST_DEBUG_OBJECT (sink, "signal waiter");
      priv->step_unlock = TRUE;
      GST_BASE_SINK_PREROLL_SIGNAL (sink);
    }
    GST_BASE_SINK_PREROLL_UNLOCK (sink);
  } else {
    /* update the stepinfo and make it valid */
    set_step_info (sink, current, pending, seqnum, format, amount, rate, flush,
        intermediate);
  }

  return TRUE;
}

/* with STREAM_LOCK
 */
static void
gst_base_sink_loop (GstPad * pad)
{
  GstObject *parent;
  GstBaseSink *basesink;
  GstBuffer *buf = NULL;
  GstFlowReturn result;
  guint blocksize;
  guint64 offset;

  parent = GST_OBJECT_PARENT (pad);
  basesink = GST_BASE_SINK (parent);

  g_assert (basesink->pad_mode == GST_PAD_MODE_PULL);

  if ((blocksize = basesink->priv->blocksize) == 0)
    blocksize = -1;

  offset = basesink->segment.position;

  GST_DEBUG_OBJECT (basesink, "pulling %" G_GUINT64_FORMAT ", %u",
      offset, blocksize);

  result = gst_pad_pull_range (pad, offset, blocksize, &buf);
  if (G_UNLIKELY (result != GST_FLOW_OK))
    goto paused;

  if (G_UNLIKELY (buf == NULL))
    goto no_buffer;

  offset += gst_buffer_get_size (buf);

  basesink->segment.position = offset;

  GST_BASE_SINK_PREROLL_LOCK (basesink);
  result = gst_base_sink_chain_unlocked (basesink, pad, buf, FALSE);
  GST_BASE_SINK_PREROLL_UNLOCK (basesink);
  if (G_UNLIKELY (result != GST_FLOW_OK))
    goto paused;

  return;

  /* ERRORS */
paused:
  {
    GST_LOG_OBJECT (basesink, "pausing task, reason %s",
        gst_flow_get_name (result));
    gst_pad_pause_task (pad);
    if (result == GST_FLOW_EOS) {
      /* perform EOS logic */
      if (basesink->segment.flags & GST_SEGMENT_FLAG_SEGMENT) {
        gst_element_post_message (GST_ELEMENT_CAST (basesink),
            gst_message_new_segment_done (GST_OBJECT_CAST (basesink),
                basesink->segment.format, basesink->segment.position));
        gst_base_sink_event (pad, parent,
            gst_event_new_segment_done (basesink->segment.format,
                basesink->segment.position));
      } else {
        gst_base_sink_event (pad, parent, gst_event_new_eos ());
      }
    } else if (result == GST_FLOW_NOT_LINKED || result <= GST_FLOW_EOS) {
      /* for fatal errors we post an error message, post the error
       * first so the app knows about the error first. 
       * wrong-state is not a fatal error because it happens due to
       * flushing and posting an error message in that case is the
       * wrong thing to do, e.g. when basesrc is doing a flushing
       * seek. */
      GST_ELEMENT_ERROR (basesink, STREAM, FAILED,
          (_("Internal data stream error.")),
          ("stream stopped, reason %s", gst_flow_get_name (result)));
      gst_base_sink_event (pad, parent, gst_event_new_eos ());
    }
    return;
  }
no_buffer:
  {
    GST_LOG_OBJECT (basesink, "no buffer, pausing");
    GST_ELEMENT_ERROR (basesink, STREAM, FAILED,
        (_("Internal data flow error.")), ("element returned NULL buffer"));
    result = GST_FLOW_ERROR;
    goto paused;
  }
}

static gboolean
gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
    gboolean flushing)
{
  GstBaseSinkClass *bclass;

  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  if (flushing) {
    /* unlock any subclasses, we need to do this before grabbing the
     * PREROLL_LOCK since we hold this lock before going into ::render. */
    if (bclass->unlock)
      bclass->unlock (basesink);
  }

  GST_BASE_SINK_PREROLL_LOCK (basesink);
  basesink->flushing = flushing;
  if (flushing) {
    /* step 1, now that we have the PREROLL lock, clear our unlock request */
    if (bclass->unlock_stop)
      bclass->unlock_stop (basesink);

    /* set need_preroll before we unblock the clock. If the clock is unblocked
     * before timing out, we can reuse the buffer for preroll. */
    basesink->need_preroll = TRUE;

    /* step 2, unblock clock sync (if any) or any other blocking thing */
    if (basesink->clock_id) {
      gst_clock_id_unschedule (basesink->clock_id);
    }

    /* flush out the data thread if it's locked in finish_preroll, this will
     * also flush out the EOS state */
    GST_DEBUG_OBJECT (basesink,
        "flushing out data thread, need preroll to TRUE");

    /* we can't have EOS anymore now */
    basesink->eos = FALSE;
    basesink->priv->received_eos = FALSE;
    basesink->have_preroll = FALSE;
    basesink->priv->step_unlock = FALSE;
    /* can't report latency anymore until we preroll again */
    if (basesink->priv->async_enabled) {
      GST_OBJECT_LOCK (basesink);
      basesink->priv->have_latency = FALSE;
      GST_OBJECT_UNLOCK (basesink);
    }
    /* and signal any waiters now */
    GST_BASE_SINK_PREROLL_SIGNAL (basesink);
  }
  GST_BASE_SINK_PREROLL_UNLOCK (basesink);

  return TRUE;
}

static gboolean
gst_base_sink_default_activate_pull (GstBaseSink * basesink, gboolean active)
{
  gboolean result;

  if (active) {
    /* start task */
    result = gst_pad_start_task (basesink->sinkpad,
        (GstTaskFunction) gst_base_sink_loop, basesink->sinkpad, NULL);
  } else {
    /* step 2, make sure streaming finishes */
    result = gst_pad_stop_task (basesink->sinkpad);
  }

  return result;
}

static gboolean
gst_base_sink_pad_activate (GstPad * pad, GstObject * parent)
{
  gboolean result = FALSE;
  GstBaseSink *basesink;
  GstQuery *query;
  gboolean pull_mode;

  basesink = GST_BASE_SINK (parent);

  GST_DEBUG_OBJECT (basesink, "Trying pull mode first");

  gst_base_sink_set_flushing (basesink, pad, FALSE);

  /* we need to have the pull mode enabled */
  if (!basesink->can_activate_pull) {
    GST_DEBUG_OBJECT (basesink, "pull mode disabled");
    goto fallback;
  }

  /* check if downstreams supports pull mode at all */
  query = gst_query_new_scheduling ();

  if (!gst_pad_peer_query (pad, query)) {
    gst_query_unref (query);
    GST_DEBUG_OBJECT (basesink, "peer query faild, no pull mode");
    goto fallback;
  }

  /* parse result of the query */
  pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
  gst_query_unref (query);

  if (!pull_mode) {
    GST_DEBUG_OBJECT (basesink, "pull mode not supported");
    goto fallback;
  }

  /* set the pad mode before starting the task so that it's in the
   * correct state for the new thread. also the sink set_caps and get_caps
   * function checks this */
  basesink->pad_mode = GST_PAD_MODE_PULL;

  /* we first try to negotiate a format so that when we try to activate
   * downstream, it knows about our format */
  if (!gst_base_sink_negotiate_pull (basesink)) {
    GST_DEBUG_OBJECT (basesink, "failed to negotiate in pull mode");
    goto fallback;
  }

  /* ok activate now */
  if (!gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE)) {
    /* clear any pending caps */
    GST_OBJECT_LOCK (basesink);
    gst_caps_replace (&basesink->priv->caps, NULL);
    GST_OBJECT_UNLOCK (basesink);
    GST_DEBUG_OBJECT (basesink, "failed to activate in pull mode");
    goto fallback;
  }

  GST_DEBUG_OBJECT (basesink, "Success activating pull mode");
  result = TRUE;
  goto done;

  /* push mode fallback */
fallback:
  GST_DEBUG_OBJECT (basesink, "Falling back to push mode");
  if ((result = gst_pad_activate_mode (pad, GST_PAD_MODE_PUSH, TRUE))) {
    GST_DEBUG_OBJECT (basesink, "Success activating push mode");
  }

done:
  if (!result) {
    GST_WARNING_OBJECT (basesink, "Could not activate pad in either mode");
    gst_base_sink_set_flushing (basesink, pad, TRUE);
  }

  return result;
}

static gboolean
gst_base_sink_pad_activate_push (GstPad * pad, GstObject * parent,
    gboolean active)
{
  gboolean result;
  GstBaseSink *basesink;

  basesink = GST_BASE_SINK (parent);

  if (active) {
    if (!basesink->can_activate_push) {
      result = FALSE;
      basesink->pad_mode = GST_PAD_MODE_NONE;
    } else {
      result = TRUE;
      basesink->pad_mode = GST_PAD_MODE_PUSH;
    }
  } else {
    if (G_UNLIKELY (basesink->pad_mode != GST_PAD_MODE_PUSH)) {
      g_warning ("Internal GStreamer activation error!!!");
      result = FALSE;
    } else {
      gst_base_sink_set_flushing (basesink, pad, TRUE);
      result = TRUE;
      basesink->pad_mode = GST_PAD_MODE_NONE;
    }
  }

  return result;
}

static gboolean
gst_base_sink_negotiate_pull (GstBaseSink * basesink)
{
  GstCaps *caps;
  gboolean result;

  result = FALSE;

  /* this returns the intersection between our caps and the peer caps. If there
   * is no peer, it returns NULL and we can't operate in pull mode so we can
   * fail the negotiation. */
  caps = gst_pad_get_allowed_caps (GST_BASE_SINK_PAD (basesink));
  if (caps == NULL || gst_caps_is_empty (caps))
    goto no_caps_possible;

  GST_DEBUG_OBJECT (basesink, "allowed caps: %" GST_PTR_FORMAT, caps);

  if (gst_caps_is_any (caps)) {
    GST_DEBUG_OBJECT (basesink, "caps were ANY after fixating, "
        "allowing pull()");
    /* neither side has template caps in this case, so they are prepared for
       pull() without setcaps() */
    result = TRUE;
  } else {
    /* try to fixate */
    caps = gst_base_sink_fixate (basesink, caps);
    GST_DEBUG_OBJECT (basesink, "fixated to: %" GST_PTR_FORMAT, caps);

    if (gst_caps_is_fixed (caps)) {
      if (!gst_pad_set_caps (GST_BASE_SINK_PAD (basesink), caps))
        goto could_not_set_caps;

      result = TRUE;
    }
  }

  gst_caps_unref (caps);

  return result;

no_caps_possible:
  {
    GST_INFO_OBJECT (basesink, "Pipeline could not agree on caps");
    GST_DEBUG_OBJECT (basesink, "get_allowed_caps() returned EMPTY");
    if (caps)
      gst_caps_unref (caps);
    return FALSE;
  }
could_not_set_caps:
  {
    GST_INFO_OBJECT (basesink, "Could not set caps: %" GST_PTR_FORMAT, caps);
    gst_caps_unref (caps);
    return FALSE;
  }
}

/* this won't get called until we implement an activate function */
static gboolean
gst_base_sink_pad_activate_pull (GstPad * pad, GstObject * parent,
    gboolean active)
{
  gboolean result = FALSE;
  GstBaseSink *basesink;
  GstBaseSinkClass *bclass;

  basesink = GST_BASE_SINK (parent);
  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  if (active) {
    gint64 duration;

    /* we mark we have a newsegment here because pull based
     * mode works just fine without having a newsegment before the
     * first buffer */
    gst_segment_init (&basesink->segment, GST_FORMAT_BYTES);
    GST_OBJECT_LOCK (basesink);
    basesink->have_newsegment = TRUE;
    GST_OBJECT_UNLOCK (basesink);

    /* get the peer duration in bytes */
    result = gst_pad_peer_query_duration (pad, GST_FORMAT_BYTES, &duration);
    if (result) {
      GST_DEBUG_OBJECT (basesink,
          "setting duration in bytes to %" G_GINT64_FORMAT, duration);
      basesink->segment.duration = duration;
    } else {
      GST_DEBUG_OBJECT (basesink, "unknown duration");
    }

    if (bclass->activate_pull)
      result = bclass->activate_pull (basesink, TRUE);
    else
      result = FALSE;

    if (!result)
      goto activate_failed;

  } else {
    if (G_UNLIKELY (basesink->pad_mode != GST_PAD_MODE_PULL)) {
      g_warning ("Internal GStreamer activation error!!!");
      result = FALSE;
    } else {
      result = gst_base_sink_set_flushing (basesink, pad, TRUE);
      if (bclass->activate_pull)
        result &= bclass->activate_pull (basesink, FALSE);
      basesink->pad_mode = GST_PAD_MODE_NONE;
    }
  }

  return result;

  /* ERRORS */
activate_failed:
  {
    /* reset, as starting the thread failed */
    basesink->pad_mode = GST_PAD_MODE_NONE;

    GST_ERROR_OBJECT (basesink, "subclass failed to activate in pull mode");
    return FALSE;
  }
}

static gboolean
gst_base_sink_pad_activate_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;

  switch (mode) {
    case GST_PAD_MODE_PULL:
      res = gst_base_sink_pad_activate_pull (pad, parent, active);
      break;
    case GST_PAD_MODE_PUSH:
      res = gst_base_sink_pad_activate_push (pad, parent, active);
      break;
    default:
      GST_LOG_OBJECT (pad, "unknown activation mode %d", mode);
      res = FALSE;
      break;
  }
  return res;
}

/* send an event to our sinkpad peer. */
static gboolean
gst_base_sink_send_event (GstElement * element, GstEvent * event)
{
  GstPad *pad;
  GstBaseSink *basesink = GST_BASE_SINK (element);
  gboolean forward, result = TRUE;
  GstPadMode mode;

  GST_OBJECT_LOCK (element);
  /* get the pad and the scheduling mode */
  pad = gst_object_ref (basesink->sinkpad);
  mode = basesink->pad_mode;
  GST_OBJECT_UNLOCK (element);

  /* only push UPSTREAM events upstream */
  forward = GST_EVENT_IS_UPSTREAM (event);

  GST_DEBUG_OBJECT (basesink, "handling event %p %" GST_PTR_FORMAT, event,
      event);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_LATENCY:
    {
      GstClockTime latency;

      gst_event_parse_latency (event, &latency);

      /* store the latency. We use this to adjust the running_time before syncing
       * it to the clock. */
      GST_OBJECT_LOCK (element);
      basesink->priv->latency = latency;
      if (!basesink->priv->have_latency)
        forward = FALSE;
      GST_OBJECT_UNLOCK (element);
      GST_DEBUG_OBJECT (basesink, "latency set to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (latency));

      /* We forward this event so that all elements know about the global pipeline
       * latency. This is interesting for an element when it wants to figure out
       * when a particular piece of data will be rendered. */
      break;
    }
    case GST_EVENT_SEEK:
      /* in pull mode we will execute the seek */
      if (mode == GST_PAD_MODE_PULL)
        result = gst_base_sink_perform_seek (basesink, pad, event);
      break;
    case GST_EVENT_STEP:
      result = gst_base_sink_perform_step (basesink, pad, event);
      forward = FALSE;
      break;
    default:
      break;
  }

  if (forward) {
    result = gst_pad_push_event (pad, event);
  } else {
    /* not forwarded, unref the event */
    gst_event_unref (event);
  }

  gst_object_unref (pad);

  GST_DEBUG_OBJECT (basesink, "handled event %p %" GST_PTR_FORMAT ": %d", event,
      event, result);

  return result;
}

static gboolean
gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
    gint64 * cur, gboolean * upstream)
{
  GstClock *clock = NULL;
  gboolean res = FALSE;
  GstFormat oformat;
  GstSegment *segment;
  GstClockTime now, latency;
  GstClockTimeDiff base_time;
  gint64 time, base, duration;
  gdouble rate;
  gint64 last;
  gboolean last_seen, with_clock, in_paused;

  GST_OBJECT_LOCK (basesink);
  /* we can only get the segment when we are not NULL or READY */
  if (!basesink->have_newsegment)
    goto wrong_state;

  in_paused = FALSE;
  /* when not in PLAYING or when we're busy with a state change, we
   * cannot read from the clock so we report time based on the
   * last seen timestamp. */
  if (GST_STATE (basesink) != GST_STATE_PLAYING ||
      GST_STATE_PENDING (basesink) != GST_STATE_VOID_PENDING) {
    in_paused = TRUE;
  }

  segment = &basesink->segment;

  /* get the format in the segment */
  oformat = segment->format;

  /* report with last seen position when EOS */
  last_seen = basesink->eos;

  /* assume we will use the clock for getting the current position */
  with_clock = TRUE;
  if (basesink->sync == FALSE)
    with_clock = FALSE;

  /* and we need a clock */
  if (G_UNLIKELY ((clock = GST_ELEMENT_CLOCK (basesink)) == NULL))
    with_clock = FALSE;
  else
    gst_object_ref (clock);

  /* mainloop might be querying position when going to playing async,
   * while (audio) rendering might be quickly advancing stream position,
   * so use clock asap rather than last reported position */
  if (in_paused && with_clock && g_atomic_int_get (&basesink->priv->to_playing)) {
    GST_DEBUG_OBJECT (basesink, "going to PLAYING, so not PAUSED");
    in_paused = FALSE;
  }

  /* collect all data we need holding the lock */
  if (GST_CLOCK_TIME_IS_VALID (segment->time))
    time = segment->time;
  else
    time = 0;

  if (GST_CLOCK_TIME_IS_VALID (segment->stop))
    duration = segment->stop - segment->start;
  else
    duration = 0;

  base = segment->base;
  rate = segment->rate * segment->applied_rate;
  latency = basesink->priv->latency;

  if (oformat == GST_FORMAT_TIME) {
    gint64 start, stop;

    start = basesink->priv->current_sstart;
    stop = basesink->priv->current_sstop;

    if (in_paused) {
      /* in paused we use the last position as a lower bound */
      if (stop == -1 || segment->rate > 0.0)
        last = start;
      else
        last = stop;
    } else {
      /* in playing, use last stop time as upper bound */
      if (start == -1 || segment->rate > 0.0)
        last = stop;
      else
        last = start;
    }
  } else {
    /* convert last stop to stream time */
    last = gst_segment_to_stream_time (segment, oformat, segment->position);
  }

  if (in_paused) {
    /* in paused, use start_time */
    base_time = GST_ELEMENT_START_TIME (basesink);
    GST_DEBUG_OBJECT (basesink, "in paused, using start time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (base_time));
  } else if (with_clock) {
    /* else use clock when needed */
    base_time = GST_ELEMENT_CAST (basesink)->base_time;
    GST_DEBUG_OBJECT (basesink, "using clock and base time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (base_time));
  } else {
    /* else, no sync or clock -> no base time */
    GST_DEBUG_OBJECT (basesink, "no sync or no clock");
    base_time = -1;
  }

  /* no base_time, we can't calculate running_time, use last seem timestamp to report
   * time */
  if (base_time == -1)
    last_seen = TRUE;

  /* need to release the object lock before we can get the time,
   * a clock might take the LOCK of the provider, which could be
   * a basesink subclass. */
  GST_OBJECT_UNLOCK (basesink);

  if (last_seen) {
    /* in EOS or when no valid stream_time, report the value of last seen
     * timestamp */
    if (last == -1) {
      /* no timestamp, we need to ask upstream */
      GST_DEBUG_OBJECT (basesink, "no last seen timestamp, asking upstream");
      res = FALSE;
      *upstream = TRUE;
      goto done;
    }
    GST_DEBUG_OBJECT (basesink, "using last seen timestamp %" GST_TIME_FORMAT,
        GST_TIME_ARGS (last));
    *cur = last;
  } else {
    if (oformat != GST_FORMAT_TIME) {
      /* convert base, time and duration to time */
      if (!gst_pad_query_convert (basesink->sinkpad, oformat, base,
              GST_FORMAT_TIME, &base))
        goto convert_failed;
      if (!gst_pad_query_convert (basesink->sinkpad, oformat, duration,
              GST_FORMAT_TIME, &duration))
        goto convert_failed;
      if (!gst_pad_query_convert (basesink->sinkpad, oformat, time,
              GST_FORMAT_TIME, &time))
        goto convert_failed;
      if (!gst_pad_query_convert (basesink->sinkpad, oformat, last,
              GST_FORMAT_TIME, &last))
        goto convert_failed;

      /* assume time format from now on */
      oformat = GST_FORMAT_TIME;
    }

    if (!in_paused && with_clock) {
      now = gst_clock_get_time (clock);
    } else {
      now = base_time;
      base_time = 0;
    }

    /* subtract base time and base time from the clock time.
     * Make sure we don't go negative. This is the current time in
     * the segment which we need to scale with the combined
     * rate and applied rate. */
    base_time += base;
    base_time += latency;
    if (GST_CLOCK_DIFF (base_time, now) < 0)
      base_time = now;

    /* for negative rates we need to count back from the segment
     * duration. */
    if (rate < 0.0)
      time += duration;

    *cur = time + gst_guint64_to_gdouble (now - base_time) * rate;

    if (in_paused) {
      /* never report less than segment values in paused */
      if (last != -1)
        *cur = MAX (last, *cur);
    } else {
      /* never report more than last seen position in playing */
      if (last != -1)
        *cur = MIN (last, *cur);
    }

    GST_DEBUG_OBJECT (basesink,
        "now %" GST_TIME_FORMAT " - base_time %" GST_TIME_FORMAT " - base %"
        GST_TIME_FORMAT " + time %" GST_TIME_FORMAT "  last %" GST_TIME_FORMAT,
        GST_TIME_ARGS (now), GST_TIME_ARGS (base_time), GST_TIME_ARGS (base),
        GST_TIME_ARGS (time), GST_TIME_ARGS (last));
  }

  if (oformat != format) {
    /* convert to final format */
    if (!gst_pad_query_convert (basesink->sinkpad, oformat, *cur, format, cur))
      goto convert_failed;
  }

  res = TRUE;

done:
  GST_DEBUG_OBJECT (basesink, "res: %d, POSITION: %" GST_TIME_FORMAT,
      res, GST_TIME_ARGS (*cur));

  if (clock)
    gst_object_unref (clock);

  return res;

  /* special cases */
wrong_state:
  {
    /* in NULL or READY we always return FALSE and -1 */
    GST_DEBUG_OBJECT (basesink, "position in wrong state, return -1");
    res = FALSE;
    *cur = -1;
    GST_OBJECT_UNLOCK (basesink);
    goto done;
  }
convert_failed:
  {
    GST_DEBUG_OBJECT (basesink, "convert failed, try upstream");
    *upstream = TRUE;
    res = FALSE;
    goto done;
  }
}

static gboolean
gst_base_sink_get_duration (GstBaseSink * basesink, GstFormat format,
    gint64 * dur, gboolean * upstream)
{
  gboolean res = FALSE;

  if (basesink->pad_mode == GST_PAD_MODE_PULL) {
    gint64 uduration;

    /* get the duration in bytes, in pull mode that's all we are sure to
     * know. We have to explicitly get this value from upstream instead of
     * using our cached value because it might change. Duration caching
     * should be done at a higher level. */
    res =
        gst_pad_peer_query_duration (basesink->sinkpad, GST_FORMAT_BYTES,
        &uduration);
    if (res) {
      basesink->segment.duration = uduration;
      if (format != GST_FORMAT_BYTES) {
        /* convert to the requested format */
        res =
            gst_pad_query_convert (basesink->sinkpad, GST_FORMAT_BYTES,
            uduration, format, dur);
      } else {
        *dur = uduration;
      }
    }
    *upstream = FALSE;
  } else {
    *upstream = TRUE;
  }

  return res;
}

static gboolean
default_element_query (GstElement * element, GstQuery * query)
{
  gboolean res = FALSE;

  GstBaseSink *basesink = GST_BASE_SINK (element);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      gint64 cur = 0;
      GstFormat format;
      gboolean upstream = FALSE;

      gst_query_parse_position (query, &format, NULL);

      GST_DEBUG_OBJECT (basesink, "position query in format %s",
          gst_format_get_name (format));

      /* first try to get the position based on the clock */
      if ((res =
              gst_base_sink_get_position (basesink, format, &cur, &upstream))) {
        gst_query_set_position (query, format, cur);
      } else if (upstream) {
        /* fallback to peer query */
        res = gst_pad_peer_query (basesink->sinkpad, query);
      }
      if (!res) {
        /* we can handle a few things if upstream failed */
        if (format == GST_FORMAT_PERCENT) {
          gint64 dur = 0;

          res = gst_base_sink_get_position (basesink, GST_FORMAT_TIME, &cur,
              &upstream);
          if (!res && upstream) {
            res =
                gst_pad_peer_query_position (basesink->sinkpad, GST_FORMAT_TIME,
                &cur);
          }
          if (res) {
            res = gst_base_sink_get_duration (basesink, GST_FORMAT_TIME, &dur,
                &upstream);
            if (!res && upstream) {
              res =
                  gst_pad_peer_query_duration (basesink->sinkpad,
                  GST_FORMAT_TIME, &dur);
            }
          }
          if (res) {
            gint64 pos;

            pos = gst_util_uint64_scale (100 * GST_FORMAT_PERCENT_SCALE, cur,
                dur);
            gst_query_set_position (query, GST_FORMAT_PERCENT, pos);
          }
        }
      }
      break;
    }
    case GST_QUERY_DURATION:
    {
      gint64 dur = 0;
      GstFormat format;
      gboolean upstream = FALSE;

      gst_query_parse_duration (query, &format, NULL);

      GST_DEBUG_OBJECT (basesink, "duration query in format %s",
          gst_format_get_name (format));

      if ((res =
              gst_base_sink_get_duration (basesink, format, &dur, &upstream))) {
        gst_query_set_duration (query, format, dur);
      } else if (upstream) {
        /* fallback to peer query */
        res = gst_pad_peer_query (basesink->sinkpad, query);
      }
      if (!res) {
        /* we can handle a few things if upstream failed */
        if (format == GST_FORMAT_PERCENT) {
          gst_query_set_duration (query, GST_FORMAT_PERCENT,
              GST_FORMAT_PERCENT_MAX);
          res = TRUE;
        }
      }
      break;
    }
    case GST_QUERY_LATENCY:
    {
      gboolean live, us_live;
      GstClockTime min, max;

      if ((res = gst_base_sink_query_latency (basesink, &live, &us_live, &min,
                  &max))) {
        gst_query_set_latency (query, live, min, max);
      }
      break;
    }
    case GST_QUERY_JITTER:
      break;
    case GST_QUERY_RATE:
      /* gst_query_set_rate (query, basesink->segment_rate); */
      res = TRUE;
      break;
    case GST_QUERY_SEGMENT:
    {
      if (basesink->pad_mode == GST_PAD_MODE_PULL) {
        gst_query_set_segment (query, basesink->segment.rate,
            GST_FORMAT_TIME, basesink->segment.start, basesink->segment.stop);
        res = TRUE;
      } else {
        res = gst_pad_peer_query (basesink->sinkpad, query);
      }
      break;
    }
    case GST_QUERY_SEEKING:
    case GST_QUERY_CONVERT:
    case GST_QUERY_FORMATS:
    default:
      res = gst_pad_peer_query (basesink->sinkpad, query);
      break;
  }
  GST_DEBUG_OBJECT (basesink, "query %s returns %d",
      GST_QUERY_TYPE_NAME (query), res);
  return res;
}


static gboolean
gst_base_sink_default_query (GstBaseSink * basesink, GstQuery * query)
{
  gboolean res;
  GstBaseSinkClass *bclass;

  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_ALLOCATION:
    {
      if (bclass->propose_allocation)
        res = bclass->propose_allocation (basesink, query);
      else
        res = FALSE;
      break;
    }
    case GST_QUERY_CAPS:
    {
      GstCaps *caps, *filter;

      gst_query_parse_caps (query, &filter);
      caps = gst_base_sink_query_caps (basesink, basesink->sinkpad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    case GST_QUERY_ACCEPT_CAPS:
    {
      GstCaps *caps, *allowed;
      gboolean subset;

      /* slightly faster than the default implementation */
      gst_query_parse_accept_caps (query, &caps);
      allowed = gst_base_sink_query_caps (basesink, basesink->sinkpad, NULL);
      subset = gst_caps_is_subset (caps, allowed);
      gst_caps_unref (allowed);
      gst_query_set_accept_caps_result (query, subset);
      res = TRUE;
      break;
    }
    case GST_QUERY_DRAIN:
      res = TRUE;
      break;
    default:
      res =
          gst_pad_query_default (basesink->sinkpad, GST_OBJECT_CAST (basesink),
          query);
      break;
  }
  return res;
}

static gboolean
gst_base_sink_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstBaseSink *basesink;
  GstBaseSinkClass *bclass;
  gboolean res;

  basesink = GST_BASE_SINK_CAST (parent);
  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  if (bclass->query)
    res = bclass->query (basesink, query);
  else
    res = FALSE;

  return res;
}

static GstStateChangeReturn
gst_base_sink_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstBaseSink *basesink = GST_BASE_SINK (element);
  GstBaseSinkClass *bclass;
  GstBaseSinkPrivate *priv;

  priv = basesink->priv;

  bclass = GST_BASE_SINK_GET_CLASS (basesink);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (bclass->start)
        if (!bclass->start (basesink))
          goto start_failed;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* need to complete preroll before this state change completes, there
       * is no data flow in READY so we can safely assume we need to preroll. */
      GST_BASE_SINK_PREROLL_LOCK (basesink);
      GST_DEBUG_OBJECT (basesink, "READY to PAUSED");
      basesink->have_newsegment = FALSE;
      gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
      basesink->offset = 0;
      basesink->have_preroll = FALSE;
      priv->step_unlock = FALSE;
      basesink->need_preroll = TRUE;
      basesink->playing_async = TRUE;
      priv->current_sstart = GST_CLOCK_TIME_NONE;
      priv->current_sstop = GST_CLOCK_TIME_NONE;
      priv->eos_rtime = GST_CLOCK_TIME_NONE;
      priv->latency = 0;
      basesink->eos = FALSE;
      priv->received_eos = FALSE;
      gst_base_sink_reset_qos (basesink);
      priv->commited = FALSE;
      priv->call_preroll = TRUE;
      priv->current_step.valid = FALSE;
      priv->pending_step.valid = FALSE;
      if (priv->async_enabled) {
        GST_DEBUG_OBJECT (basesink, "doing async state change");
        /* when async enabled, post async-start message and return ASYNC from
         * the state change function */
        ret = GST_STATE_CHANGE_ASYNC;
        gst_element_post_message (GST_ELEMENT_CAST (basesink),
            gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
      } else {
        priv->have_latency = TRUE;
      }
      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      GST_BASE_SINK_PREROLL_LOCK (basesink);
      g_atomic_int_set (&basesink->priv->to_playing, TRUE);
      if (!gst_base_sink_needs_preroll (basesink)) {
        GST_DEBUG_OBJECT (basesink, "PAUSED to PLAYING, don't need preroll");
        /* no preroll needed anymore now. */
        basesink->playing_async = FALSE;
        basesink->need_preroll = FALSE;
        if (basesink->eos) {
          GstMessage *message;

          /* need to post EOS message here */
          GST_DEBUG_OBJECT (basesink, "Now posting EOS");
          message = gst_message_new_eos (GST_OBJECT_CAST (basesink));
          gst_message_set_seqnum (message, basesink->priv->seqnum);
          gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
        } else {
          GST_DEBUG_OBJECT (basesink, "signal preroll");
          GST_BASE_SINK_PREROLL_SIGNAL (basesink);
        }
      } else {
        GST_DEBUG_OBJECT (basesink, "PAUSED to PLAYING, we are not prerolled");
        basesink->need_preroll = TRUE;
        basesink->playing_async = TRUE;
        priv->call_preroll = TRUE;
        priv->commited = FALSE;
        if (priv->async_enabled) {
          GST_DEBUG_OBJECT (basesink, "doing async state change");
          ret = GST_STATE_CHANGE_ASYNC;
          gst_element_post_message (GST_ELEMENT_CAST (basesink),
              gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
        }
      }
      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
      break;
    default:
      break;
  }

  {
    GstStateChangeReturn bret;

    bret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
    if (G_UNLIKELY (bret == GST_STATE_CHANGE_FAILURE))
      goto activate_failed;
  }

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      /* completed transition, so need not be marked any longer
       * And it should be unmarked, since e.g. losing our position upon flush
       * does not really change state to PAUSED ... */
      g_atomic_int_set (&basesink->priv->to_playing, FALSE);
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      g_atomic_int_set (&basesink->priv->to_playing, FALSE);
      GST_DEBUG_OBJECT (basesink, "PLAYING to PAUSED");
      /* FIXME, make sure we cannot enter _render first */

      /* we need to call ::unlock before locking PREROLL_LOCK
       * since we lock it before going into ::render */
      if (bclass->unlock)
        bclass->unlock (basesink);

      GST_BASE_SINK_PREROLL_LOCK (basesink);
      GST_DEBUG_OBJECT (basesink, "got preroll lock");
      /* now that we have the PREROLL lock, clear our unlock request */
      if (bclass->unlock_stop)
        bclass->unlock_stop (basesink);

      /* we need preroll again and we set the flag before unlocking the clockid
       * because if the clockid is unlocked before a current buffer expired, we
       * can use that buffer to preroll with */
      basesink->need_preroll = TRUE;

      if (basesink->clock_id) {
        GST_DEBUG_OBJECT (basesink, "unschedule clock");
        gst_clock_id_unschedule (basesink->clock_id);
      }

      /* if we don't have a preroll buffer we need to wait for a preroll and
       * return ASYNC. */
      if (!gst_base_sink_needs_preroll (basesink)) {
        GST_DEBUG_OBJECT (basesink, "PLAYING to PAUSED, we are prerolled");
        basesink->playing_async = FALSE;
      } else {
        if (GST_STATE_TARGET (GST_ELEMENT (basesink)) <= GST_STATE_READY) {
          GST_DEBUG_OBJECT (basesink, "element is <= READY");
          ret = GST_STATE_CHANGE_SUCCESS;
        } else {
          GST_DEBUG_OBJECT (basesink,
              "PLAYING to PAUSED, we are not prerolled");
          basesink->playing_async = TRUE;
          priv->commited = FALSE;
          priv->call_preroll = TRUE;
          if (priv->async_enabled) {
            GST_DEBUG_OBJECT (basesink, "doing async state change");
            ret = GST_STATE_CHANGE_ASYNC;
            gst_element_post_message (GST_ELEMENT_CAST (basesink),
                gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
          }
        }
      }
      GST_DEBUG_OBJECT (basesink, "rendered: %" G_GUINT64_FORMAT
          ", dropped: %" G_GUINT64_FORMAT, priv->rendered, priv->dropped);

      gst_base_sink_reset_qos (basesink);
      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_BASE_SINK_PREROLL_LOCK (basesink);
      /* start by resetting our position state with the object lock so that the
       * position query gets the right idea. We do this before we post the
       * messages so that the message handlers pick this up. */
      GST_OBJECT_LOCK (basesink);
      basesink->have_newsegment = FALSE;
      priv->current_sstart = GST_CLOCK_TIME_NONE;
      priv->current_sstop = GST_CLOCK_TIME_NONE;
      priv->have_latency = FALSE;
      if (priv->cached_clock_id) {
        gst_clock_id_unref (priv->cached_clock_id);
        priv->cached_clock_id = NULL;
      }
      gst_caps_replace (&basesink->priv->caps, NULL);
      GST_OBJECT_UNLOCK (basesink);

      gst_base_sink_set_last_buffer (basesink, NULL);
      priv->call_preroll = FALSE;

      if (!priv->commited) {
        if (priv->async_enabled) {
          GST_DEBUG_OBJECT (basesink, "PAUSED to READY, posting async-done");

          gst_element_post_message (GST_ELEMENT_CAST (basesink),
              gst_message_new_state_changed (GST_OBJECT_CAST (basesink),
                  GST_STATE_PLAYING, GST_STATE_PAUSED, GST_STATE_READY));

          gst_element_post_message (GST_ELEMENT_CAST (basesink),
              gst_message_new_async_done (GST_OBJECT_CAST (basesink),
                  GST_CLOCK_TIME_NONE));
        }
        priv->commited = TRUE;
      } else {
        GST_DEBUG_OBJECT (basesink, "PAUSED to READY, don't need_preroll");
      }
      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      if (bclass->stop) {
        if (!bclass->stop (basesink)) {
          GST_WARNING_OBJECT (basesink, "failed to stop");
        }
      }
      gst_base_sink_set_last_buffer (basesink, NULL);
      priv->call_preroll = FALSE;
      break;
    default:
      break;
  }

  return ret;

  /* ERRORS */
start_failed:
  {
    GST_DEBUG_OBJECT (basesink, "failed to start");
    return GST_STATE_CHANGE_FAILURE;
  }
activate_failed:
  {
    GST_DEBUG_OBJECT (basesink,
        "element failed to change states -- activation problem?");
    return GST_STATE_CHANGE_FAILURE;
  }
}
