/* 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, 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:
 * |[<!-- language="C" -->
 * 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_static_pad_template (gstelement_class, &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_SEGMENT 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 overridden 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.
 */

#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, avg_in_diff;
  gdouble avg_rate;             /* average with infinite window */

  /* 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;
  GstBufferList *last_buffer_list;

  /* 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;

  /* for rate control */
  guint64 max_bitrate;
  GstClockTime rc_time;
  GstClockTime rc_next;
  gsize rc_accumulated;
};

#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.
 * positive 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
#define DEFAULT_MAX_BITRATE         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_MAX_BITRATE,
  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, gboolean render);

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 buffer.
   */
  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 2.0: 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 = disabled)", 0,
          G_MAXUINT64, DEFAULT_THROTTLE_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstBaseSink:max-bitrate:
   *
   * Control the maximum amount of bits that will be rendered per second.
   * Setting this property to a value bigger than 0 will make the sink delay
   * rendering of the buffers when it would exceed to max-bitrate.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_MAX_BITRATE,
      g_param_spec_uint64 ("max-bitrate", "Max Bitrate",
          "The maximum bits per second to render (0 = disabled)", 0,
          G_MAXUINT64, DEFAULT_MAX_BITRATE,
          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;
  priv->max_bitrate = DEFAULT_MAX_BITRATE;

  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 incoming
 * 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 asynchronously. 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) (nullable): 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_list) {
    GstBuffer *first_buffer = NULL;

    /* Set the first buffer in the list to last sample's buffer */
    first_buffer = gst_buffer_list_get (sink->priv->last_buffer_list, 0);
    res =
        gst_sample_new (first_buffer, sink->priv->last_caps, &sink->segment,
        NULL);
    gst_sample_set_buffer_list (res, sink->priv->last_buffer_list);
  } else 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);
  }
}

/* with OBJECT_LOCK */
static void
gst_base_sink_set_last_buffer_list_unlocked (GstBaseSink * sink,
    GstBufferList * buffer_list)
{
  GstBufferList *old;

  old = sink->priv->last_buffer_list;
  if (G_LIKELY (old != buffer_list)) {
    GST_DEBUG_OBJECT (sink, "setting last buffer list to %p", buffer_list);
    if (G_LIKELY (buffer_list))
      gst_mini_object_ref (GST_MINI_OBJECT_CAST (buffer_list));
    sink->priv->last_buffer_list = buffer_list;
  } 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_mini_object_unref (GST_MINI_OBJECT_CAST (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);
}

static void
gst_base_sink_set_last_buffer_list (GstBaseSink * sink,
    GstBufferList * buffer_list)
{
  if (!g_atomic_int_get (&sink->priv->enable_last_sample))
    return;

  GST_OBJECT_LOCK (sink);
  gst_base_sink_set_last_buffer_list_unlocked (sink, buffer_list);
  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_base_sink_set_last_buffer_list_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 positive 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 */
        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 2.0: 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 2.0: 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;
}

/**
 * gst_base_sink_set_max_bitrate:
 * @sink: a #GstBaseSink
 * @max_bitrate: the max_bitrate in bits per second
 *
 * Set the maximum amount of bits per second that the sink will render.
 *
 * Since: 1.2
 */
void
gst_base_sink_set_max_bitrate (GstBaseSink * sink, guint64 max_bitrate)
{
  g_return_if_fail (GST_IS_BASE_SINK (sink));

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

/**
 * gst_base_sink_get_max_bitrate:
 * @sink: a #GstBaseSink
 *
 * Get the maximum amount of bits per second that the sink will render.
 *
 * Returns: the maximum number of bits per second @sink will render.
 *
 * Since: 1.2
 */
guint64
gst_base_sink_get_max_bitrate (GstBaseSink * sink)
{
  guint64 res;

  g_return_val_if_fail (GST_IS_BASE_SINK (sink), 0);

  GST_OBJECT_LOCK (sink);
  res = sink->priv->max_bitrate;
  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;
    case PROP_MAX_BITRATE:
      gst_base_sink_set_max_bitrate (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_sample (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;
    case PROP_MAX_BITRATE:
      g_value_set_uint64 (value, gst_base_sink_get_max_bitrate (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) {
    if (post_paused) {
      GstElementClass *klass;

      klass = GST_ELEMENT_GET_CLASS (basesink);
      basesink->have_preroll = TRUE;
      /* after releasing this lock, the state change function
       * can execute concurrently with this thread. There is nothing we do to
       * prevent this for now. subclasses should be prepared to handle it. */
      GST_BASE_SINK_PREROLL_UNLOCK (basesink);

      if (klass->change_state)
        klass->change_state (GST_ELEMENT_CAST (basesink),
            GST_STATE_CHANGE_PAUSED_TO_PLAYING);

      GST_BASE_SINK_PREROLL_LOCK (basesink);
      /* state change function could have been executed and we could be
       * flushing now */
      if (G_UNLIKELY (basesink->flushing))
        goto stopping_unlocked;
    }
    GST_DEBUG_OBJECT (basesink, "posting PLAYING state change message");
    /* FIXME, we released the PREROLL lock above, it's possible that this
     * message is not correct anymore when the element went back to PAUSED */
    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_unlocked:
  {
    GST_OBJECT_LOCK (basesink);
    goto stopping;
  }
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_position_from_running_time (segment, GST_FORMAT_TIME,
              end);
        else
          position = segment->stop;

        segment->stop = position;
        segment->position = position;
      } else {
        if (end != -1)
          position =
              gst_segment_position_from_running_time (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_position_from_running_time (segment, GST_FORMAT_TIME,
              end);
        } else {
          *rstop = end;
          *cstop =
              gst_segment_position_from_running_time (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, GstClockTime * rrnext,
    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, rnext; /* 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 = rnext = 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 (GST_CLOCK_TIME_IS_VALID (stop))
    rnext = rstop;
  else
    rnext = rstart;

  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;
  *rrnext = rnext;

  /* 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 careful 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 synchronisation 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);
        gst_base_sink_set_last_buffer (sink, buf);
        gst_base_sink_set_last_buffer_list (sink, GST_BUFFER_LIST_CAST (obj));
        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);
        gst_base_sink_set_last_buffer_list (sink, NULL);
      } 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, rnext, sstart, sstop, stime;
  gboolean do_sync;
  GstBaseSinkPrivate *priv;
  GstFlowReturn ret;
  GstStepInfo *current, *pending;
  gboolean stepped;

  priv = basesink->priv;

do_step:
  sstart = sstop = rstart = rstop = rnext = 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, &rnext, &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 ? rnext : 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);

  /* adjust for rate control */
  if (priv->rc_next == -1 || (stime != -1 && stime >= priv->rc_next)) {
    GST_DEBUG_OBJECT (basesink, "reset rc_time to time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (stime));
    priv->rc_time = stime;
    priv->rc_accumulated = 0;
  } else {
    GST_DEBUG_OBJECT (basesink, "rate control next %" GST_TIME_FORMAT,
        GST_TIME_ARGS (priv->rc_next));
    stime = priv->rc_next;
  }

  /* 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, TRUE);

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, only use buffer durations if not in
   * trick mode or key-unit mode. Otherwise the buffer durations will be
   * meaningless as frames are being dropped in-between without updating the
   * durations. */
  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_pt: %" GST_TIME_FORMAT ", avg_rate: %g",
      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_pt))
    priv->avg_pt = pt;
  else
    priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt);

  if (duration != -1 && duration != 0) {
    rate =
        gst_guint64_to_gdouble (priv->avg_pt) /
        gst_guint64_to_gdouble (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_pt: %" GST_TIME_FORMAT
      ", avg_rate: %g", 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_pt = GST_CLOCK_TIME_NONE;
  priv->avg_rate = -1.0;
  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 render)
{
  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 (render && (!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;
  }
}

static void
gst_base_sink_update_start_time (GstBaseSink * basesink)
{
  GstClock *clock;

  GST_OBJECT_LOCK (basesink);
  if (GST_STATE (basesink) == GST_STATE_PLAYING
      && (clock = GST_ELEMENT_CLOCK (basesink))) {
    GstClockTime now;

    gst_object_ref (clock);
    GST_OBJECT_UNLOCK (basesink);

    /* calculate the time when we stopped */
    now = gst_clock_get_time (clock);
    gst_object_unref (clock);

    GST_OBJECT_LOCK (basesink);
    /* store the current running time */
    if (GST_ELEMENT_START_TIME (basesink) != GST_CLOCK_TIME_NONE) {
      if (now != GST_CLOCK_TIME_NONE)
        GST_ELEMENT_START_TIME (basesink) =
            now - GST_ELEMENT_CAST (basesink)->base_time;
      else
        GST_WARNING_OBJECT (basesink,
            "Clock %s returned invalid time, can't calculate "
            "running_time when going to the PAUSED state",
            GST_OBJECT_NAME (clock));
    }
    GST_DEBUG_OBJECT (basesink,
        "start_time=%" GST_TIME_FORMAT ", now=%" GST_TIME_FORMAT
        ", base_time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_ELEMENT_START_TIME (basesink)),
        GST_TIME_ARGS (now),
        GST_TIME_ARGS (GST_ELEMENT_CAST (basesink)->base_time));
  }
  GST_OBJECT_UNLOCK (basesink);
}

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_base_sink_update_start_time (basesink);
    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_base_sink_set_last_buffer_list (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_ELEMENT_START_TIME (basesink) = 0;
    }
  }
  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 = FALSE;

  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;
      guint group_id;

      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));
      if (gst_event_parse_group_id (event, &group_id)) {
        gst_message_set_group_id (message, group_id);
      } else {
        GST_FIXME_OBJECT (basesink, "stream-start event without group-id. "
            "Consider implementing group-id handling in the upstream "
            "elements");
      }
      gst_message_set_seqnum (message, seqnum);
      gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
      break;
    }
    case GST_EVENT_CAPS:
    {
      GstCaps *caps, *current_caps;

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

      gst_event_parse_caps (event, &caps);
      current_caps = gst_pad_get_current_caps (GST_BASE_SINK_PAD (basesink));

      if (current_caps && gst_caps_is_equal (current_caps, caps)) {
        GST_DEBUG_OBJECT (basesink,
            "New caps equal to old ones: %" GST_PTR_FORMAT, caps);
      } else {
        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);
        }
      }
      if (current_caps)
        gst_caps_unref (current_caps);
      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_base_sink_reset_qos (basesink);
      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;
}

static gboolean
count_list_bytes (GstBuffer ** buffer, guint idx, GstBaseSinkPrivate * priv)
{
  priv->rc_accumulated += gst_buffer_get_size (*buffer);
  return TRUE;
}

/* 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 = GST_FLOW_OK;
  GstClockTime start = GST_CLOCK_TIME_NONE, end = GST_CLOCK_TIME_NONE;
  GstSegment *segment;
  GstBuffer *sync_buf;
  gboolean late, step_end, prepared = FALSE;

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

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

  if (is_list) {
    GstBufferList *buffer_list = GST_BUFFER_LIST_CAST (obj);

    if (gst_buffer_list_length (buffer_list) == 0)
      goto empty_list;

    sync_buf = gst_buffer_list_get (buffer_list, 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. Buffer can only be
   * dropped if their PTS falls completly outside the segment, while we sync
   * preferably on DTS */
  if (GST_CLOCK_TIME_IS_VALID (start) && (segment->format == GST_FORMAT_TIME)) {
    GstClockTime pts = GST_BUFFER_PTS (sync_buf);
    GstClockTime pts_end = GST_CLOCK_TIME_NONE;

    if (!GST_CLOCK_TIME_IS_VALID (pts))
      pts = start;

    if (GST_CLOCK_TIME_IS_VALID (end))
      pts_end = pts + (end - start);

    if (G_UNLIKELY (!gst_segment_clip (segment,
                GST_FORMAT_TIME, pts, pts_end, NULL, NULL)))
      goto out_of_segment;
  }

  if (bclass->prepare || bclass->prepare_list) {
    gboolean do_sync = TRUE, stepped = FALSE, syncable = TRUE;
    GstClockTime sstart, sstop, rstart, rstop, rnext;
    GstStepInfo *current;

    late = FALSE;
    step_end = FALSE;

    current = &priv->current_step;
    syncable =
        gst_base_sink_get_sync_times (basesink, obj, &sstart, &sstop, &rstart,
        &rstop, &rnext, &do_sync, &stepped, current, &step_end);

    if (G_UNLIKELY (stepped))
      goto dropped;

    if (syncable && do_sync && gst_base_sink_get_sync (basesink)) {
      GstClock *clock;

      GST_OBJECT_LOCK (basesink);
      clock = GST_ELEMENT_CLOCK (basesink);
      if (clock && GST_STATE (basesink) == GST_STATE_PLAYING) {
        GstClockTime base_time;
        GstClockTime stime;
        GstClockTime now;

        base_time = GST_ELEMENT_CAST (basesink)->base_time;
        stime = base_time + gst_base_sink_adjust_time (basesink, rstart);
        now = gst_clock_get_time (clock);
        GST_OBJECT_UNLOCK (basesink);

        late =
            gst_base_sink_is_too_late (basesink, obj, rstart, rstop,
            GST_CLOCK_EARLY, GST_CLOCK_DIFF (stime, now), FALSE);
      } else {
        GST_OBJECT_UNLOCK (basesink);
      }
    }

    if (G_UNLIKELY (late))
      goto dropped;

    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;
      }
    }

    prepared = TRUE;
  }

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;

  /* Don't skip if prepare() was called on time */
  late = late && !prepared;

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

  if (priv->max_bitrate) {
    if (is_list) {
      gst_buffer_list_foreach (GST_BUFFER_LIST_CAST (obj),
          (GstBufferListFunc) count_list_bytes, priv);
    } else {
      priv->rc_accumulated += gst_buffer_get_size (GST_BUFFER_CAST (obj));
    }
    priv->rc_next = priv->rc_time + gst_util_uint64_scale (priv->rc_accumulated,
        8 * GST_SECOND, priv->max_bitrate);
  }

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

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

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

    if (bclass->render_list)
      ret = bclass->render_list (basesink, buffer_list);

    /* Set the first buffer and buffer list to be included in last sample */
    gst_base_sink_set_last_buffer (basesink, sync_buf);
    gst_base_sink_set_last_buffer_list (basesink, buffer_list);
  }

  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;
  }
empty_list:
  {
    GST_DEBUG_OBJECT (basesink, "buffer list with no buffers");
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (obj));
    return GST_FLOW_OK;
  }
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_LOG_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;
  }

  GST_INFO_OBJECT (sink, "seeking done %d: %" GST_SEGMENT_FORMAT, res,
      &seeksegment);

  /* 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_base_sink_update_start_time (sink);
      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_set_last_buffer_list (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_FLOW_ERROR (basesink, 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) {
    GST_DEBUG_OBJECT (basesink, "sending event %p %" GST_PTR_FORMAT, event,
        event);
    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: %d", 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)
    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 (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;

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

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

    if (last_seen) {
      /* when we don't use the clock, we use the last position as a lower bound */
      if (stop == -1 || segment->rate > 0.0)
        last = start;
      else
        last = stop;

      GST_DEBUG_OBJECT (basesink, "in PAUSED using last %" GST_TIME_FORMAT,
          GST_TIME_ARGS (last));
    } else {
      /* in playing and paused, use last stop time as upper bound */
      if (start == -1 || segment->rate > 0.0)
        last = stop;
      else
        last = start;

      GST_DEBUG_OBJECT (basesink, "in PLAYING using last %" GST_TIME_FORMAT,
          GST_TIME_ARGS (last));
    }
  } else {
    /* convert position to stream time */
    last = gst_segment_to_stream_time (segment, oformat, segment->position);

    GST_DEBUG_OBJECT (basesink, "in using last %" G_GINT64_FORMAT, last);
  }

  /* 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;

    /* never report more than last seen position */
    if (last != -1) {
      if (rate > 0.0)
        *cur = MIN (last, *cur);
      else
        *cur = MAX (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) {
        GstFormat format;
        gint64 start, stop;

        format = basesink->segment.format;

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

        gst_query_set_segment (query, basesink->segment.rate, format, start,
            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 void
gst_base_sink_drain (GstBaseSink * basesink)
{
  GstBuffer *old;
  GstBufferList *old_list;

  GST_OBJECT_LOCK (basesink);
  if ((old = basesink->priv->last_buffer))
    basesink->priv->last_buffer = gst_buffer_copy_deep (old);

  if ((old_list = basesink->priv->last_buffer_list))
    basesink->priv->last_buffer_list = gst_buffer_list_copy_deep (old_list);
  GST_OBJECT_UNLOCK (basesink);

  if (old)
    gst_buffer_unref (old);
  if (old_list)
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (old_list));
}

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:
    {
      gst_base_sink_drain (basesink);
      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_DEBUG_OBJECT (basesink, "Checking if requested caps %" GST_PTR_FORMAT
          " are a subset of pad caps %" GST_PTR_FORMAT " result %d", caps,
          allowed, subset);
      gst_caps_unref (allowed);
      gst_query_set_accept_caps_result (query, subset);
      res = TRUE;
      break;
    }
    case GST_QUERY_DRAIN:
    {
      gst_base_sink_drain (basesink);
      res = TRUE;
      break;
    }
    case GST_QUERY_POSITION:
    {
      res = default_element_query (GST_ELEMENT (basesink), query);
      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->rc_next = -1;
      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);

      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;
        basesink->need_preroll = 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;
          basesink->need_preroll = 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);
      gst_base_sink_set_last_buffer_list (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);
      gst_base_sink_set_last_buffer_list (basesink, NULL);
      priv->call_preroll = FALSE;
      break;
    default:
      break;
  }

  return ret;

  /* ERRORS */
start_failed:
  {
    GST_DEBUG_OBJECT (basesink, "failed to start");
    /* subclass is supposed to post a message but we post one as a fallback
     * just in case */
    GST_ELEMENT_ERROR (basesink, CORE, STATE_CHANGE, (NULL),
        ("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;
  }
}
