/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2005 Wim Taymans <wim@fluendo.com>
 *
 * gstaudiobasesink.c:
 *
 * 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:gstaudiobasesink
 * @title: GstAudioBaseSink
 * @short_description: Base class for audio sinks
 * @see_also: #GstAudioSink, #GstAudioRingBuffer.
 *
 * This is the base class for audio sinks. Subclasses need to implement the
 * ::create_ringbuffer vmethod. This base class will then take care of
 * writing samples to the ringbuffer, synchronisation, clipping and flushing.
 */

#include <string.h>

#include <gst/audio/audio.h>
#include "gstaudiobasesink.h"

GST_DEBUG_CATEGORY_STATIC (gst_audio_base_sink_debug);
#define GST_CAT_DEFAULT gst_audio_base_sink_debug

#define GST_AUDIO_BASE_SINK_GET_PRIVATE(obj)  \
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_BASE_SINK, GstAudioBaseSinkPrivate))

struct _GstAudioBaseSinkPrivate
{
  /* upstream latency */
  GstClockTime us_latency;
  /* the clock slaving algorithm in use */
  GstAudioBaseSinkSlaveMethod slave_method;
  /* running average of clock skew */
  GstClockTimeDiff avg_skew;
  /* the number of samples we aligned last time */
  gint64 last_align;

  gboolean sync_latency;

  GstClockTime eos_time;

  /* number of microseconds we allow clock slaving to drift
   * before resyncing */
  guint64 drift_tolerance;

  /* number of nanoseconds we allow timestamps to drift
   * before resyncing */
  GstClockTime alignment_threshold;

  /* time of the previous detected discont candidate */
  GstClockTime discont_time;

  /* number of nanoseconds to wait until creating a discontinuity */
  GstClockTime discont_wait;

  /* custom slaving algorithm callback */
  GstAudioBaseSinkCustomSlavingCallback custom_slaving_callback;
  gpointer custom_slaving_cb_data;
  GDestroyNotify custom_slaving_cb_notify;
};

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

/* FIXME: 2.0, store the buffer_time and latency_time in nanoseconds */
#define DEFAULT_BUFFER_TIME     ((200 * GST_MSECOND) / GST_USECOND)
#define DEFAULT_LATENCY_TIME    ((10 * GST_MSECOND) / GST_USECOND)
#define DEFAULT_PROVIDE_CLOCK   TRUE
#define DEFAULT_SLAVE_METHOD    GST_AUDIO_BASE_SINK_SLAVE_SKEW

/* FIXME, enable pull mode when clock slaving and trick modes are figured out */
#define DEFAULT_CAN_ACTIVATE_PULL FALSE

/* when timestamps drift for more than 40ms we resync. This should
 * be enough to compensate for timestamp rounding errors. */
#define DEFAULT_ALIGNMENT_THRESHOLD   (40 * GST_MSECOND)

/* when clock slaving drift for more than 40ms we resync. This is
 * a reasonable default */
#define DEFAULT_DRIFT_TOLERANCE   ((40 * GST_MSECOND) / GST_USECOND)

/* allow for one second before resyncing to see if the timestamps drift will
 * fix itself, or is a permanent offset */
#define DEFAULT_DISCONT_WAIT        (1 * GST_SECOND)

enum
{
  PROP_0,

  PROP_BUFFER_TIME,
  PROP_LATENCY_TIME,
  PROP_PROVIDE_CLOCK,
  PROP_SLAVE_METHOD,
  PROP_CAN_ACTIVATE_PULL,
  PROP_ALIGNMENT_THRESHOLD,
  PROP_DRIFT_TOLERANCE,
  PROP_DISCONT_WAIT,

  PROP_LAST
};

#define _do_init \
    GST_DEBUG_CATEGORY_INIT (gst_audio_base_sink_debug, "audiobasesink", 0, "audiobasesink element");
#define gst_audio_base_sink_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstAudioBaseSink, gst_audio_base_sink,
    GST_TYPE_BASE_SINK, _do_init);

static void gst_audio_base_sink_dispose (GObject * object);

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

static GstStateChangeReturn gst_audio_base_sink_change_state (GstElement *
    element, GstStateChange transition);
static gboolean gst_audio_base_sink_activate_pull (GstBaseSink * basesink,
    gboolean active);
static gboolean gst_audio_base_sink_query (GstElement * element, GstQuery *
    query);

static GstClock *gst_audio_base_sink_provide_clock (GstElement * elem);
static inline void gst_audio_base_sink_reset_sync (GstAudioBaseSink * sink);
static GstClockTime gst_audio_base_sink_get_time (GstClock * clock,
    GstAudioBaseSink * sink);
static void gst_audio_base_sink_callback (GstAudioRingBuffer * rbuf,
    guint8 * data, guint len, gpointer user_data);

static GstFlowReturn gst_audio_base_sink_preroll (GstBaseSink * bsink,
    GstBuffer * buffer);
static GstFlowReturn gst_audio_base_sink_render (GstBaseSink * bsink,
    GstBuffer * buffer);
static gboolean gst_audio_base_sink_event (GstBaseSink * bsink,
    GstEvent * event);
static GstFlowReturn gst_audio_base_sink_wait_event (GstBaseSink * bsink,
    GstEvent * event);
static void gst_audio_base_sink_get_times (GstBaseSink * bsink,
    GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
static gboolean gst_audio_base_sink_setcaps (GstBaseSink * bsink,
    GstCaps * caps);
static GstCaps *gst_audio_base_sink_fixate (GstBaseSink * bsink,
    GstCaps * caps);

static gboolean gst_audio_base_sink_query_pad (GstBaseSink * bsink,
    GstQuery * query);


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

static void
gst_audio_base_sink_class_init (GstAudioBaseSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *gstbasesink_class;

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

  g_type_class_add_private (klass, sizeof (GstAudioBaseSinkPrivate));

  gobject_class->set_property = gst_audio_base_sink_set_property;
  gobject_class->get_property = gst_audio_base_sink_get_property;
  gobject_class->dispose = gst_audio_base_sink_dispose;

  g_object_class_install_property (gobject_class, PROP_BUFFER_TIME,
      g_param_spec_int64 ("buffer-time", "Buffer Time",
          "Size of audio buffer in microseconds, this is the minimum "
          "latency that the sink reports", 1, G_MAXINT64, DEFAULT_BUFFER_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_LATENCY_TIME,
      g_param_spec_int64 ("latency-time", "Latency Time",
          "The minimum amount of data to write in each iteration "
          "in microseconds", 1, G_MAXINT64, DEFAULT_LATENCY_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PROVIDE_CLOCK,
      g_param_spec_boolean ("provide-clock", "Provide Clock",
          "Provide a clock to be used as the global pipeline clock",
          DEFAULT_PROVIDE_CLOCK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_SLAVE_METHOD,
      g_param_spec_enum ("slave-method", "Slave Method",
          "Algorithm used to match the rate of the masterclock",
          GST_TYPE_AUDIO_BASE_SINK_SLAVE_METHOD, DEFAULT_SLAVE_METHOD,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_CAN_ACTIVATE_PULL,
      g_param_spec_boolean ("can-activate-pull", "Allow Pull Scheduling",
          "Allow pull-based scheduling", DEFAULT_CAN_ACTIVATE_PULL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstAudioBaseSink:drift-tolerance:
   *
   * Controls the amount of time in microseconds that clocks are allowed
   * to drift before resynchronisation happens.
   */
  g_object_class_install_property (gobject_class, PROP_DRIFT_TOLERANCE,
      g_param_spec_int64 ("drift-tolerance", "Drift Tolerance",
          "Tolerance for clock drift in microseconds", 1,
          G_MAXINT64, DEFAULT_DRIFT_TOLERANCE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstAudioBaseSink:alignment_threshold:
   *
   * Controls the amount of time in nanoseconds that timestamps are allowed
   * to drift from their ideal time before choosing not to align them.
   */
  g_object_class_install_property (gobject_class, PROP_ALIGNMENT_THRESHOLD,
      g_param_spec_uint64 ("alignment-threshold", "Alignment Threshold",
          "Timestamp alignment threshold in nanoseconds", 1,
          G_MAXUINT64 - 1, DEFAULT_ALIGNMENT_THRESHOLD,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstAudioBaseSink:discont-wait:
   *
   * A window of time in nanoseconds to wait before creating a discontinuity as
   * a result of breaching the drift-tolerance.
   */
  g_object_class_install_property (gobject_class, PROP_DISCONT_WAIT,
      g_param_spec_uint64 ("discont-wait", "Discont Wait",
          "Window of time in nanoseconds to wait before "
          "creating a discontinuity", 0,
          G_MAXUINT64 - 1, DEFAULT_DISCONT_WAIT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_audio_base_sink_change_state);
  gstelement_class->provide_clock =
      GST_DEBUG_FUNCPTR (gst_audio_base_sink_provide_clock);
  gstelement_class->query = GST_DEBUG_FUNCPTR (gst_audio_base_sink_query);

  gstbasesink_class->fixate = GST_DEBUG_FUNCPTR (gst_audio_base_sink_fixate);
  gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_base_sink_setcaps);
  gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_audio_base_sink_event);
  gstbasesink_class->wait_event =
      GST_DEBUG_FUNCPTR (gst_audio_base_sink_wait_event);
  gstbasesink_class->get_times =
      GST_DEBUG_FUNCPTR (gst_audio_base_sink_get_times);
  gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_audio_base_sink_preroll);
  gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_audio_base_sink_render);
  gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_audio_base_sink_query_pad);
  gstbasesink_class->activate_pull =
      GST_DEBUG_FUNCPTR (gst_audio_base_sink_activate_pull);

  /* ref class from a thread-safe context to work around missing bit of
   * thread-safety in GObject */
  g_type_class_ref (GST_TYPE_AUDIO_CLOCK);
  g_type_class_ref (GST_TYPE_AUDIO_RING_BUFFER);

}

static void
gst_audio_base_sink_init (GstAudioBaseSink * audiobasesink)
{
  GstBaseSink *basesink;

  audiobasesink->priv = GST_AUDIO_BASE_SINK_GET_PRIVATE (audiobasesink);

  audiobasesink->buffer_time = DEFAULT_BUFFER_TIME;
  audiobasesink->latency_time = DEFAULT_LATENCY_TIME;
  audiobasesink->priv->slave_method = DEFAULT_SLAVE_METHOD;
  audiobasesink->priv->drift_tolerance = DEFAULT_DRIFT_TOLERANCE;
  audiobasesink->priv->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
  audiobasesink->priv->discont_wait = DEFAULT_DISCONT_WAIT;
  audiobasesink->priv->custom_slaving_callback = NULL;
  audiobasesink->priv->custom_slaving_cb_data = NULL;
  audiobasesink->priv->custom_slaving_cb_notify = NULL;

  audiobasesink->provided_clock = gst_audio_clock_new ("GstAudioSinkClock",
      (GstAudioClockGetTimeFunc) gst_audio_base_sink_get_time, audiobasesink,
      NULL);

  basesink = GST_BASE_SINK_CAST (audiobasesink);
  basesink->can_activate_push = TRUE;
  basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL;

  gst_base_sink_set_last_sample_enabled (basesink, FALSE);
  if (DEFAULT_PROVIDE_CLOCK)
    GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
  else
    GST_OBJECT_FLAG_UNSET (basesink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
}

static void
gst_audio_base_sink_dispose (GObject * object)
{
  GstAudioBaseSink *sink;

  sink = GST_AUDIO_BASE_SINK (object);

  if (sink->priv->custom_slaving_cb_notify)
    sink->priv->custom_slaving_cb_notify (sink->priv->custom_slaving_cb_data);

  if (sink->provided_clock) {
    gst_audio_clock_invalidate (GST_AUDIO_CLOCK (sink->provided_clock));
    gst_object_unref (sink->provided_clock);
    sink->provided_clock = NULL;
  }

  if (sink->ringbuffer) {
    gst_object_unparent (GST_OBJECT_CAST (sink->ringbuffer));
    sink->ringbuffer = NULL;
  }

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


static GstClock *
gst_audio_base_sink_provide_clock (GstElement * elem)
{
  GstAudioBaseSink *sink;
  GstClock *clock;

  sink = GST_AUDIO_BASE_SINK (elem);

  /* we have no ringbuffer (must be NULL state) */
  if (sink->ringbuffer == NULL)
    goto wrong_state;

  if (!gst_audio_ring_buffer_is_acquired (sink->ringbuffer))
    goto wrong_state;

  GST_OBJECT_LOCK (sink);
  if (!GST_OBJECT_FLAG_IS_SET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK))
    goto clock_disabled;

  clock = GST_CLOCK_CAST (gst_object_ref (sink->provided_clock));
  GST_OBJECT_UNLOCK (sink);

  return clock;

  /* ERRORS */
wrong_state:
  {
    GST_DEBUG_OBJECT (sink, "ringbuffer not acquired");
    return NULL;
  }
clock_disabled:
  {
    GST_DEBUG_OBJECT (sink, "clock provide disabled");
    GST_OBJECT_UNLOCK (sink);
    return NULL;
  }
}

static gboolean
gst_audio_base_sink_is_self_provided_clock (GstAudioBaseSink * sink)
{
  return (sink->provided_clock && GST_IS_AUDIO_CLOCK (sink->provided_clock) &&
      GST_AUDIO_CLOCK_CAST (sink->provided_clock)->func ==
      (GstAudioClockGetTimeFunc) gst_audio_base_sink_get_time);
}

static gboolean
gst_audio_base_sink_query_pad (GstBaseSink * bsink, GstQuery * query)
{
  gboolean res = FALSE;
  GstAudioBaseSink *basesink;

  basesink = GST_AUDIO_BASE_SINK (bsink);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      GST_LOG_OBJECT (basesink, "query convert");

      if (basesink->ringbuffer) {
        gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
        res =
            gst_audio_ring_buffer_convert (basesink->ringbuffer, src_fmt,
            src_val, dest_fmt, &dest_val);
        if (res) {
          gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
        }
      }
      break;
    }
    default:
      res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
      break;
  }
  return res;
}

static gboolean
gst_audio_base_sink_query (GstElement * element, GstQuery * query)
{
  gboolean res = FALSE;
  GstAudioBaseSink *basesink;

  basesink = GST_AUDIO_BASE_SINK (element);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:
    {
      gboolean live, us_live;
      GstClockTime min_l, max_l;

      GST_DEBUG_OBJECT (basesink, "latency query");

      /* ask parent first, it will do an upstream query for us. */
      if ((res =
              gst_base_sink_query_latency (GST_BASE_SINK_CAST (basesink), &live,
                  &us_live, &min_l, &max_l))) {
        GstClockTime base_latency, min_latency, max_latency;

        /* we and upstream are both live, adjust the min_latency */
        if (live && us_live) {
          GstAudioRingBufferSpec *spec;

          GST_OBJECT_LOCK (basesink);
          if (!basesink->ringbuffer || !basesink->ringbuffer->spec.info.rate) {
            GST_OBJECT_UNLOCK (basesink);

            GST_DEBUG_OBJECT (basesink,
                "we are not negotiated, can't report latency yet");
            res = FALSE;
            goto done;
          }
          spec = &basesink->ringbuffer->spec;

          basesink->priv->us_latency = min_l;

          base_latency =
              gst_util_uint64_scale_int (spec->seglatency * spec->segsize,
              GST_SECOND, spec->info.rate * spec->info.bpf);
          GST_OBJECT_UNLOCK (basesink);

          /* we cannot go lower than the buffer size and the min peer latency */
          min_latency = base_latency + min_l;
          /* the max latency is the max of the peer, we can delay an infinite
           * amount of time. */
          max_latency = (max_l == -1) ? -1 : (base_latency + max_l);

          GST_DEBUG_OBJECT (basesink,
              "peer min %" GST_TIME_FORMAT ", our min latency: %"
              GST_TIME_FORMAT, GST_TIME_ARGS (min_l),
              GST_TIME_ARGS (min_latency));
          GST_DEBUG_OBJECT (basesink,
              "peer max %" GST_TIME_FORMAT ", our max latency: %"
              GST_TIME_FORMAT, GST_TIME_ARGS (max_l),
              GST_TIME_ARGS (max_latency));
        } else {
          GST_DEBUG_OBJECT (basesink,
              "peer or we are not live, don't care about latency");
          min_latency = min_l;
          max_latency = max_l;
        }
        gst_query_set_latency (query, live, min_latency, max_latency);
      }
      break;
    }
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      GST_LOG_OBJECT (basesink, "query convert");

      if (basesink->ringbuffer) {
        gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
        res =
            gst_audio_ring_buffer_convert (basesink->ringbuffer, src_fmt,
            src_val, dest_fmt, &dest_val);
        if (res) {
          gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
        }
      }
      break;
    }
    default:
      res = GST_ELEMENT_CLASS (parent_class)->query (element, query);
      break;
  }

done:
  return res;
}


/* we call this function without holding the lock on sink for performance
 * reasons. Try hard to not deal with and invalid ringbuffer and rate. */
static GstClockTime
gst_audio_base_sink_get_time (GstClock * clock, GstAudioBaseSink * sink)
{
  guint64 raw, samples;
  guint delay;
  GstClockTime result;
  GstAudioRingBuffer *ringbuffer;
  gint rate;

  if ((ringbuffer = sink->ringbuffer) == NULL)
    return GST_CLOCK_TIME_NONE;

  if ((rate = ringbuffer->spec.info.rate) == 0)
    return GST_CLOCK_TIME_NONE;

  /* our processed samples are always increasing */
  raw = samples = gst_audio_ring_buffer_samples_done (ringbuffer);

  /* the number of samples not yet processed, this is still queued in the
   * device (not played for playback). */
  delay = gst_audio_ring_buffer_delay (ringbuffer);

  if (G_LIKELY (samples >= delay))
    samples -= delay;
  else
    samples = 0;

  result = gst_util_uint64_scale_int (samples, GST_SECOND, rate);

  GST_DEBUG_OBJECT (sink,
      "processed samples: raw %" G_GUINT64_FORMAT ", delay %u, real %"
      G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT,
      raw, delay, samples, GST_TIME_ARGS (result));

  return result;
}

/**
 * gst_audio_base_sink_set_provide_clock:
 * @sink: a #GstAudioBaseSink
 * @provide: new state
 *
 * Controls whether @sink will provide a clock or not. If @provide is %TRUE,
 * gst_element_provide_clock() will return a clock that reflects the datarate
 * of @sink. If @provide is %FALSE, gst_element_provide_clock() will return
 * NULL.
 */
void
gst_audio_base_sink_set_provide_clock (GstAudioBaseSink * sink,
    gboolean provide)
{
  g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  if (provide)
    GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
  else
    GST_OBJECT_FLAG_UNSET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_audio_base_sink_get_provide_clock:
 * @sink: a #GstAudioBaseSink
 *
 * Queries whether @sink will provide a clock or not. See also
 * gst_audio_base_sink_set_provide_clock.
 *
 * Returns: %TRUE if @sink will provide a clock.
 */
gboolean
gst_audio_base_sink_get_provide_clock (GstAudioBaseSink * sink)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), FALSE);

  GST_OBJECT_LOCK (sink);
  result = GST_OBJECT_FLAG_IS_SET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
  GST_OBJECT_UNLOCK (sink);

  return result;
}

/**
 * gst_audio_base_sink_set_slave_method:
 * @sink: a #GstAudioBaseSink
 * @method: the new slave method
 *
 * Controls how clock slaving will be performed in @sink.
 */
void
gst_audio_base_sink_set_slave_method (GstAudioBaseSink * sink,
    GstAudioBaseSinkSlaveMethod method)
{
  g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->priv->slave_method = method;
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_audio_base_sink_get_slave_method:
 * @sink: a #GstAudioBaseSink
 *
 * Get the current slave method used by @sink.
 *
 * Returns: The current slave method used by @sink.
 */
GstAudioBaseSinkSlaveMethod
gst_audio_base_sink_get_slave_method (GstAudioBaseSink * sink)
{
  GstAudioBaseSinkSlaveMethod result;

  g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), -1);

  GST_OBJECT_LOCK (sink);
  result = sink->priv->slave_method;
  GST_OBJECT_UNLOCK (sink);

  return result;
}


/**
 * gst_audio_base_sink_set_drift_tolerance:
 * @sink: a #GstAudioBaseSink
 * @drift_tolerance: the new drift tolerance in microseconds
 *
 * Controls the sink's drift tolerance.
 */
void
gst_audio_base_sink_set_drift_tolerance (GstAudioBaseSink * sink,
    gint64 drift_tolerance)
{
  g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->priv->drift_tolerance = drift_tolerance;
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_audio_base_sink_get_drift_tolerance:
 * @sink: a #GstAudioBaseSink
 *
 * Get the current drift tolerance, in microseconds, used by @sink.
 *
 * Returns: The current drift tolerance used by @sink.
 */
gint64
gst_audio_base_sink_get_drift_tolerance (GstAudioBaseSink * sink)
{
  gint64 result;

  g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), -1);

  GST_OBJECT_LOCK (sink);
  result = sink->priv->drift_tolerance;
  GST_OBJECT_UNLOCK (sink);

  return result;
}

/**
 * gst_audio_base_sink_set_alignment_threshold:
 * @sink: a #GstAudioBaseSink
 * @alignment_threshold: the new alignment threshold in nanoseconds
 *
 * Controls the sink's alignment threshold.
 */
void
gst_audio_base_sink_set_alignment_threshold (GstAudioBaseSink * sink,
    GstClockTime alignment_threshold)
{
  g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->priv->alignment_threshold = alignment_threshold;
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_audio_base_sink_get_alignment_threshold:
 * @sink: a #GstAudioBaseSink
 *
 * Get the current alignment threshold, in nanoseconds, used by @sink.
 *
 * Returns: The current alignment threshold used by @sink.
 */
GstClockTime
gst_audio_base_sink_get_alignment_threshold (GstAudioBaseSink * sink)
{
  GstClockTime result;

  g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), GST_CLOCK_TIME_NONE);

  GST_OBJECT_LOCK (sink);
  result = sink->priv->alignment_threshold;
  GST_OBJECT_UNLOCK (sink);

  return result;
}

/**
 * gst_audio_base_sink_set_discont_wait:
 * @sink: a #GstAudioBaseSink
 * @discont_wait: the new discont wait in nanoseconds
 *
 * Controls how long the sink will wait before creating a discontinuity.
 */
void
gst_audio_base_sink_set_discont_wait (GstAudioBaseSink * sink,
    GstClockTime discont_wait)
{
  g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->priv->discont_wait = discont_wait;
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_audio_base_sink_set_custom_slaving_callback:
 * @sink: a #GstAudioBaseSink
 * @callback: a #GstAudioBaseSinkCustomSlavingCallback
 * @user_data: user data passed to the callback
 * @notify : called when user_data becomes unused
 *
 * Sets the custom slaving callback. This callback will
 * be invoked if the slave-method property is set to
 * GST_AUDIO_BASE_SINK_SLAVE_CUSTOM and the audio sink
 * receives and plays samples.
 *
 * Setting the callback to NULL causes the sink to
 * behave as if the GST_AUDIO_BASE_SINK_SLAVE_NONE
 * method were used.
 *
 * Since: 1.6
 */
void
gst_audio_base_sink_set_custom_slaving_callback (GstAudioBaseSink * sink,
    GstAudioBaseSinkCustomSlavingCallback callback,
    gpointer user_data, GDestroyNotify notify)
{
  g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  sink->priv->custom_slaving_callback = callback;
  sink->priv->custom_slaving_cb_data = user_data;
  sink->priv->custom_slaving_cb_notify = notify;
  GST_OBJECT_UNLOCK (sink);
}

static void
gst_audio_base_sink_custom_cb_report_discont (GstAudioBaseSink * sink,
    GstAudioBaseSinkDiscontReason discont_reason)
{
  if ((sink->priv->custom_slaving_callback != NULL) &&
      (sink->priv->slave_method == GST_AUDIO_BASE_SINK_SLAVE_CUSTOM)) {
    sink->priv->custom_slaving_callback (sink, GST_CLOCK_TIME_NONE,
        GST_CLOCK_TIME_NONE, NULL, discont_reason,
        sink->priv->custom_slaving_cb_data);
  }
}

/**
 * gst_audio_base_sink_report_device_failure:
 * @sink: a #GstAudioBaseSink
 *
 * Informs this base class that the audio output device has failed for
 * some reason, causing a discontinuity (for example, because the device
 * recovered from the error, but lost all contents of its ring buffer).
 * This function is typically called by derived classes, and is useful
 * for the custom slave method.
 *
 * Since: 1.6
 */
void
gst_audio_base_sink_report_device_failure (GstAudioBaseSink * sink)
{
  g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));

  GST_OBJECT_LOCK (sink);
  gst_audio_base_sink_custom_cb_report_discont (sink,
      GST_AUDIO_BASE_SINK_DISCONT_REASON_DEVICE_FAILURE);
  GST_OBJECT_UNLOCK (sink);
}

/**
 * gst_audio_base_sink_get_discont_wait:
 * @sink: a #GstAudioBaseSink
 *
 * Get the current discont wait, in nanoseconds, used by @sink.
 *
 * Returns: The current discont wait used by @sink.
 */
GstClockTime
gst_audio_base_sink_get_discont_wait (GstAudioBaseSink * sink)
{
  GstClockTime result;

  g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), -1);

  GST_OBJECT_LOCK (sink);
  result = sink->priv->discont_wait;
  GST_OBJECT_UNLOCK (sink);

  return result;
}

static void
gst_audio_base_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioBaseSink *sink;

  sink = GST_AUDIO_BASE_SINK (object);

  switch (prop_id) {
    case PROP_BUFFER_TIME:
      sink->buffer_time = g_value_get_int64 (value);
      break;
    case PROP_LATENCY_TIME:
      sink->latency_time = g_value_get_int64 (value);
      break;
    case PROP_PROVIDE_CLOCK:
      gst_audio_base_sink_set_provide_clock (sink, g_value_get_boolean (value));
      break;
    case PROP_SLAVE_METHOD:
      gst_audio_base_sink_set_slave_method (sink, g_value_get_enum (value));
      break;
    case PROP_CAN_ACTIVATE_PULL:
      GST_BASE_SINK (sink)->can_activate_pull = g_value_get_boolean (value);
      break;
    case PROP_DRIFT_TOLERANCE:
      gst_audio_base_sink_set_drift_tolerance (sink, g_value_get_int64 (value));
      break;
    case PROP_ALIGNMENT_THRESHOLD:
      gst_audio_base_sink_set_alignment_threshold (sink,
          g_value_get_uint64 (value));
      break;
    case PROP_DISCONT_WAIT:
      gst_audio_base_sink_set_discont_wait (sink, g_value_get_uint64 (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_audio_base_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioBaseSink *sink;

  sink = GST_AUDIO_BASE_SINK (object);

  switch (prop_id) {
    case PROP_BUFFER_TIME:
      g_value_set_int64 (value, sink->buffer_time);
      break;
    case PROP_LATENCY_TIME:
      g_value_set_int64 (value, sink->latency_time);
      break;
    case PROP_PROVIDE_CLOCK:
      g_value_set_boolean (value, gst_audio_base_sink_get_provide_clock (sink));
      break;
    case PROP_SLAVE_METHOD:
      g_value_set_enum (value, gst_audio_base_sink_get_slave_method (sink));
      break;
    case PROP_CAN_ACTIVATE_PULL:
      g_value_set_boolean (value, GST_BASE_SINK (sink)->can_activate_pull);
      break;
    case PROP_DRIFT_TOLERANCE:
      g_value_set_int64 (value, gst_audio_base_sink_get_drift_tolerance (sink));
      break;
    case PROP_ALIGNMENT_THRESHOLD:
      g_value_set_uint64 (value,
          gst_audio_base_sink_get_alignment_threshold (sink));
      break;
    case PROP_DISCONT_WAIT:
      g_value_set_uint64 (value, gst_audio_base_sink_get_discont_wait (sink));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_audio_base_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
{
  GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (bsink);
  GstAudioRingBufferSpec *spec;
  GstClockTime now, internal_time;
  GstClockTime crate_num, crate_denom;

  if (!sink->ringbuffer)
    return FALSE;

  spec = &sink->ringbuffer->spec;

  if (G_UNLIKELY (spec->caps && gst_caps_is_equal (spec->caps, caps))) {
    GST_DEBUG_OBJECT (sink,
        "Ringbuffer caps haven't changed, skipping reconfiguration");
    return TRUE;
  }

  GST_DEBUG_OBJECT (sink, "release old ringbuffer");

  /* get current time, updates the last_time. When the subclass has a clock that
   * restarts from 0 when a new format is negotiated, it will call
   * gst_audio_clock_reset() which will use this last_time to create an offset
   * so that time from the clock keeps on increasing monotonically. */
  now = gst_clock_get_time (sink->provided_clock);
  internal_time = gst_clock_get_internal_time (sink->provided_clock);

  GST_DEBUG_OBJECT (sink, "time was %" GST_TIME_FORMAT, GST_TIME_ARGS (now));

  /* release old ringbuffer */
  gst_audio_ring_buffer_pause (sink->ringbuffer);
  gst_audio_ring_buffer_activate (sink->ringbuffer, FALSE);
  gst_audio_ring_buffer_release (sink->ringbuffer);

  GST_DEBUG_OBJECT (sink, "parse caps");

  spec->buffer_time = sink->buffer_time;
  spec->latency_time = sink->latency_time;

  /* parse new caps */
  if (!gst_audio_ring_buffer_parse_caps (spec, caps))
    goto parse_error;

  gst_audio_ring_buffer_debug_spec_buff (spec);

  GST_DEBUG_OBJECT (sink, "acquire ringbuffer");
  if (!gst_audio_ring_buffer_acquire (sink->ringbuffer, spec))
    goto acquire_error;

  /* If we use our own clock, we need to adjust the offset since it will now
   * restart from zero */
  if (gst_audio_base_sink_is_self_provided_clock (sink))
    gst_audio_clock_reset (GST_AUDIO_CLOCK (sink->provided_clock), 0);

  /* We need to resync since the ringbuffer restarted */
  gst_audio_base_sink_reset_sync (sink);

  gst_audio_base_sink_custom_cb_report_discont (sink,
      GST_AUDIO_BASE_SINK_DISCONT_REASON_NEW_CAPS);

  if (bsink->pad_mode == GST_PAD_MODE_PUSH) {
    GST_DEBUG_OBJECT (sink, "activate ringbuffer");
    gst_audio_ring_buffer_activate (sink->ringbuffer, TRUE);
  }

  /* due to possible changes in the spec file we should recalibrate the clock */
  gst_clock_get_calibration (sink->provided_clock, NULL, NULL,
      &crate_num, &crate_denom);
  gst_clock_set_calibration (sink->provided_clock,
      internal_time, now, crate_num, crate_denom);

  /* calculate actual latency and buffer times.
   * FIXME: In 2.0, store the latency_time internally in ns */
  spec->latency_time = gst_util_uint64_scale (spec->segsize,
      (GST_SECOND / GST_USECOND), spec->info.rate * spec->info.bpf);

  spec->buffer_time = spec->segtotal * spec->latency_time;

  gst_audio_ring_buffer_debug_spec_buff (spec);

  gst_element_post_message (GST_ELEMENT_CAST (bsink),
      gst_message_new_latency (GST_OBJECT (bsink)));

  return TRUE;

  /* ERRORS */
parse_error:
  {
    GST_DEBUG_OBJECT (sink, "could not parse caps");
    GST_ELEMENT_ERROR (sink, STREAM, FORMAT,
        (NULL), ("cannot parse audio format."));
    return FALSE;
  }
acquire_error:
  {
    GST_DEBUG_OBJECT (sink, "could not acquire ringbuffer");
    return FALSE;
  }
}

static GstCaps *
gst_audio_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps)
{
  GstStructure *s;
  gint width, depth;

  caps = gst_caps_make_writable (caps);

  s = gst_caps_get_structure (caps, 0);

  /* fields for all formats */
  gst_structure_fixate_field_nearest_int (s, "rate", 44100);
  gst_structure_fixate_field_nearest_int (s, "channels", 2);
  gst_structure_fixate_field_nearest_int (s, "width", 16);

  /* fields for int */
  if (gst_structure_has_field (s, "depth")) {
    gst_structure_get_int (s, "width", &width);
    /* round width to nearest multiple of 8 for the depth */
    depth = GST_ROUND_UP_8 (width);
    gst_structure_fixate_field_nearest_int (s, "depth", depth);
  }
  if (gst_structure_has_field (s, "signed"))
    gst_structure_fixate_field_boolean (s, "signed", TRUE);
  if (gst_structure_has_field (s, "endianness"))
    gst_structure_fixate_field_nearest_int (s, "endianness", G_BYTE_ORDER);

  caps = GST_BASE_SINK_CLASS (parent_class)->fixate (bsink, caps);

  return caps;
}

static inline void
gst_audio_base_sink_reset_sync (GstAudioBaseSink * sink)
{
  sink->next_sample = -1;
  sink->priv->eos_time = -1;
  sink->priv->discont_time = -1;
  sink->priv->avg_skew = -1;
  sink->priv->last_align = 0;
}

static void
gst_audio_base_sink_get_times (GstBaseSink * bsink, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end)
{
  /* our clock sync is a bit too much for the base class to handle so
   * we implement it ourselves. */
  *start = GST_CLOCK_TIME_NONE;
  *end = GST_CLOCK_TIME_NONE;
}

static void
gst_audio_base_sink_force_start (GstAudioBaseSink * sink)
{
  /* Set the eos_rendering flag so sub-classes definitely start the clock.
   * FIXME 2.0: Pass this as a flag to gst_audio_ring_buffer_start() */
  g_atomic_int_set (&sink->eos_rendering, 1);
  gst_audio_ring_buffer_start (sink->ringbuffer);
  g_atomic_int_set (&sink->eos_rendering, 0);
}

/* This waits for the drain to happen and can be canceled */
static GstFlowReturn
gst_audio_base_sink_drain (GstAudioBaseSink * sink)
{
  GstFlowReturn ret = GST_FLOW_OK;
  if (!sink->ringbuffer)
    return ret;
  if (!sink->ringbuffer->spec.info.rate)
    return ret;

  /* if PLAYING is interrupted,
   * arrange to have clock running when going to PLAYING again */
  g_atomic_int_set (&sink->eos_rendering, 1);

  /* need to start playback before we can drain, but only when
   * we have successfully negotiated a format and thus acquired the
   * ringbuffer. */
  if (gst_audio_ring_buffer_is_acquired (sink->ringbuffer))
    gst_audio_ring_buffer_start (sink->ringbuffer);

  if (sink->priv->eos_time != -1) {
    GST_DEBUG_OBJECT (sink,
        "last sample time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (sink->priv->eos_time));

    /* wait for the EOS time to be reached, this is the time when the last
     * sample is played. */
    ret = gst_base_sink_wait (GST_BASE_SINK (sink), sink->priv->eos_time, NULL);

    GST_DEBUG_OBJECT (sink, "drained audio");
  }
  g_atomic_int_set (&sink->eos_rendering, 0);
  return ret;
}

static GstFlowReturn
gst_audio_base_sink_wait_event (GstBaseSink * bsink, GstEvent * event)
{
  GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (bsink);
  GstFlowReturn ret = GST_FLOW_OK;
  gboolean clear_force_start_flag = FALSE;

  /* For both gap and EOS events, make sure the ringbuffer is running
   * before trying to wait on the event! */
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    case GST_EVENT_GAP:
      /* We must have a negotiated format before starting the ringbuffer */
      if (G_UNLIKELY (!gst_audio_ring_buffer_is_acquired (sink->ringbuffer))) {
  /*      GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL),
            ("Sink not negotiated before %s event.",
                GST_EVENT_TYPE_NAME (event)));

        return GST_FLOW_ERROR;
   */
        /* consider there might be chance that corrupt audio track without output buffer and not negotiated.
             We'd better not return error and quit play, video track can keep playing.*/
        GST_ERROR_OBJECT(sink, "Sink not negotiated before %s event.",GST_EVENT_TYPE_NAME (event));
      }

      gst_audio_base_sink_force_start (sink);
      /* Make sure the ringbuffer will start again if interrupted during event_wait() */
      g_atomic_int_set (&sink->eos_rendering, 1);
      clear_force_start_flag = TRUE;
      break;
    default:
      break;
  }

  ret = GST_BASE_SINK_CLASS (parent_class)->wait_event (bsink, event);
  if (ret != GST_FLOW_OK)
    goto done;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
      /* now wait till we played everything */
      ret = gst_audio_base_sink_drain (sink);
      break;
    default:
      break;
  }

done:
  if (clear_force_start_flag)
    g_atomic_int_set (&sink->eos_rendering, 0);
  return ret;
}

static gboolean
gst_audio_base_sink_event (GstBaseSink * bsink, GstEvent * event)
{
  GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (bsink);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      if (sink->ringbuffer)
        gst_audio_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
      break;
    case GST_EVENT_FLUSH_STOP:
      /* always resync on sample after a flush */
      gst_audio_base_sink_reset_sync (sink);

      gst_audio_base_sink_custom_cb_report_discont (sink,
          GST_AUDIO_BASE_SINK_DISCONT_REASON_FLUSH);

      if (sink->ringbuffer)
        gst_audio_ring_buffer_set_flushing (sink->ringbuffer, FALSE);
      break;
    default:
      break;
  }
  return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
}

static GstFlowReturn
gst_audio_base_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
{
  GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (bsink);

  if (!gst_audio_ring_buffer_is_acquired (sink->ringbuffer))
    goto wrong_state;

  /* we don't really do anything when prerolling. We could make a
   * property to play this buffer to have some sort of scrubbing
   * support. */
  return GST_FLOW_OK;

wrong_state:
  {
    GST_DEBUG_OBJECT (sink, "ringbuffer in wrong state");
    GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("sink not negotiated."));
    return GST_FLOW_NOT_NEGOTIATED;
  }
}

static guint64
gst_audio_base_sink_get_offset (GstAudioBaseSink * sink)
{
  guint64 sample, sps;
  gint writeseg, segdone;
  gint diff;

  /* assume we can append to the previous sample */
  sample = sink->next_sample;
  /* no previous sample, try to insert at position 0 */
  if (sample == -1)
    sample = 0;

  sps = sink->ringbuffer->samples_per_seg;

  /* figure out the segment and the offset inside the segment where
   * the sample should be written. */
  writeseg = sample / sps;

  /* get the currently processed segment */
  segdone = g_atomic_int_get (&sink->ringbuffer->segdone)
      - sink->ringbuffer->segbase;

  /* see how far away it is from the write segment */
  diff = writeseg - segdone;
  if (diff < 0) {
    /* sample would be dropped, position to next playable position */
    sample = (segdone + 1) * sps;
  }

  return sample;
}

static GstClockTime
clock_convert_external (GstClockTime external, GstClockTime cinternal,
    GstClockTime cexternal, GstClockTime crate_num, GstClockTime crate_denom)
{
  /* adjust for rate and speed */
  if (external >= cexternal) {
    external =
        gst_util_uint64_scale (external - cexternal, crate_denom, crate_num);
    external += cinternal;
  } else {
    external =
        gst_util_uint64_scale (cexternal - external, crate_denom, crate_num);
    if (cinternal > external)
      external = cinternal - external;
    else
      external = 0;
  }
  return external;
}


/* apply the clock offset and invoke a custom callback
 * which might also request changes to the playout pointer
 *
 * this reuses code from the skewing algorithm, but leaves
 * decision on whether or not to skew (and how much to skew)
 * up to the callback */
static void
gst_audio_base_sink_custom_slaving (GstAudioBaseSink * sink,
    GstClockTime render_start, GstClockTime render_stop,
    GstClockTime * srender_start, GstClockTime * srender_stop)
{
  GstClockTime cinternal, cexternal, crate_num, crate_denom;
  GstClockTime etime, itime;
  GstClockTimeDiff requested_skew;
  gint driftsamples;
  gint64 last_align;

  /* get calibration parameters to compensate for offsets */
  gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
      &crate_num, &crate_denom);

  /* sample clocks and figure out clock skew */
  etime = gst_clock_get_time (GST_ELEMENT_CLOCK (sink));
  itime = gst_audio_clock_get_time (GST_AUDIO_CLOCK (sink->provided_clock));
  itime =
      gst_audio_clock_adjust (GST_AUDIO_CLOCK (sink->provided_clock), itime);

  GST_DEBUG_OBJECT (sink,
      "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT
      " cinternal %" GST_TIME_FORMAT " cexternal %" GST_TIME_FORMAT,
      GST_TIME_ARGS (itime), GST_TIME_ARGS (etime),
      GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal));

  /* make sure we never go below 0 */
  etime = etime > cexternal ? etime - cexternal : 0;
  itime = itime > cinternal ? itime - cinternal : 0;

  /* don't do any skewing unless the callback explicitely requests one */
  requested_skew = 0;

  if (sink->priv->custom_slaving_callback != NULL) {
    sink->priv->custom_slaving_callback (sink, etime, itime, &requested_skew,
        FALSE, sink->priv->custom_slaving_cb_data);
    GST_DEBUG_OBJECT (sink, "custom slaving requested skew %" GST_STIME_FORMAT,
        GST_STIME_ARGS (requested_skew));
  } else {
    GST_DEBUG_OBJECT (sink,
        "no custom slaving callback set - clock drift will not be compensated");
  }

  if (requested_skew > 0) {
    cexternal = (cexternal > requested_skew) ? (cexternal - requested_skew) : 0;

    driftsamples =
        (sink->ringbuffer->spec.info.rate * requested_skew) / GST_SECOND;
    last_align = sink->priv->last_align;

    /* if we were aligning in the wrong direction or we aligned more than what we
     * will correct, resync */
    if ((last_align < 0) || (last_align > driftsamples))
      sink->next_sample = -1;

    GST_DEBUG_OBJECT (sink,
        "last_align %" G_GINT64_FORMAT " driftsamples %u, next %"
        G_GUINT64_FORMAT, last_align, driftsamples, sink->next_sample);

    gst_clock_set_calibration (sink->provided_clock, cinternal, cexternal,
        crate_num, crate_denom);
  } else if (requested_skew < 0) {
    cexternal += ABS (requested_skew);

    driftsamples =
        (sink->ringbuffer->spec.info.rate * ABS (requested_skew)) / GST_SECOND;
    last_align = sink->priv->last_align;

    /* if we were aligning in the wrong direction or we aligned more than what we
     * will correct, resync */
    if ((last_align > 0) || (-last_align > driftsamples))
      sink->next_sample = -1;

    GST_DEBUG_OBJECT (sink,
        "last_align %" G_GINT64_FORMAT " driftsamples %u, next %"
        G_GUINT64_FORMAT, last_align, driftsamples, sink->next_sample);

    gst_clock_set_calibration (sink->provided_clock, cinternal, cexternal,
        crate_num, crate_denom);
  }

  /* convert, ignoring speed */
  render_start = clock_convert_external (render_start, cinternal, cexternal,
      crate_num, crate_denom);
  render_stop = clock_convert_external (render_stop, cinternal, cexternal,
      crate_num, crate_denom);

  *srender_start = render_start;
  *srender_stop = render_stop;
}

/* algorithm to calculate sample positions that will result in resampling to
 * match the clock rate of the master */
static void
gst_audio_base_sink_resample_slaving (GstAudioBaseSink * sink,
    GstClockTime render_start, GstClockTime render_stop,
    GstClockTime * srender_start, GstClockTime * srender_stop)
{
  GstClockTime cinternal, cexternal;
  GstClockTime crate_num, crate_denom;

  /* FIXME, we can sample and add observations here or use the timeouts on the
   * clock. No idea which one is better or more stable. The timeout seems more
   * arbitrary but this one seems more demanding and does not work when there is
   * no data comming in to the sink. */
#if 0
  GstClockTime etime, itime;
  gdouble r_squared;

  /* sample clocks and figure out clock skew */
  etime = gst_clock_get_time (GST_ELEMENT_CLOCK (sink));
  itime = gst_audio_clock_get_time (sink->provided_clock);

  /* add new observation */
  gst_clock_add_observation (sink->provided_clock, itime, etime, &r_squared);
#endif

  /* get calibration parameters to compensate for speed and offset differences
   * when we are slaved */
  gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
      &crate_num, &crate_denom);

  GST_DEBUG_OBJECT (sink, "internal %" GST_TIME_FORMAT " external %"
      GST_TIME_FORMAT " %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f",
      GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal), crate_num,
      crate_denom, gst_guint64_to_gdouble (crate_num) /
      gst_guint64_to_gdouble (crate_denom));

  if (crate_num == 0)
    crate_denom = crate_num = 1;

  /* bring external time to internal time */
  render_start = clock_convert_external (render_start, cinternal, cexternal,
      crate_num, crate_denom);
  render_stop = clock_convert_external (render_stop, cinternal, cexternal,
      crate_num, crate_denom);

  GST_DEBUG_OBJECT (sink,
      "after slaving: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
      GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));

  *srender_start = render_start;
  *srender_stop = render_stop;
}

/* algorithm to calculate sample positions that will result in changing the
 * playout pointer to match the clock rate of the master */
static void
gst_audio_base_sink_skew_slaving (GstAudioBaseSink * sink,
    GstClockTime render_start, GstClockTime render_stop,
    GstClockTime * srender_start, GstClockTime * srender_stop)
{
  GstClockTime cinternal, cexternal, crate_num, crate_denom;
  GstClockTime etime, itime;
  GstClockTimeDiff skew, mdrift, mdrift2;
  gint driftsamples;
  gint64 last_align;

  /* get calibration parameters to compensate for offsets */
  gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
      &crate_num, &crate_denom);

  /* sample clocks and figure out clock skew */
  etime = gst_clock_get_time (GST_ELEMENT_CLOCK (sink));
  itime = gst_audio_clock_get_time (GST_AUDIO_CLOCK (sink->provided_clock));
  itime =
      gst_audio_clock_adjust (GST_AUDIO_CLOCK (sink->provided_clock), itime);

  GST_DEBUG_OBJECT (sink,
      "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT
      " cinternal %" GST_TIME_FORMAT " cexternal %" GST_TIME_FORMAT,
      GST_TIME_ARGS (itime), GST_TIME_ARGS (etime),
      GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal));

  /* make sure we never go below 0 */
  etime = etime > cexternal ? etime - cexternal : 0;
  itime = itime > cinternal ? itime - cinternal : 0;

  /* do itime - etime.
   * positive value means external clock goes slower
   * negative value means external clock goes faster */
  skew = GST_CLOCK_DIFF (etime, itime);
  if (sink->priv->avg_skew == -1) {
    /* first observation */
    sink->priv->avg_skew = skew;
  } else {
    /* next observations use a moving average */
    sink->priv->avg_skew = (31 * sink->priv->avg_skew + skew) / 32;
  }

  GST_DEBUG_OBJECT (sink, "internal %" GST_TIME_FORMAT " external %"
      GST_TIME_FORMAT " skew %" GST_STIME_FORMAT " avg %" GST_STIME_FORMAT,
      GST_TIME_ARGS (itime), GST_TIME_ARGS (etime), GST_STIME_ARGS (skew),
      GST_STIME_ARGS (sink->priv->avg_skew));

  /* the max drift we allow */
  mdrift = sink->priv->drift_tolerance * 1000;
  mdrift2 = mdrift / 2;

  /* adjust playout pointer based on skew */
  if (sink->priv->avg_skew > mdrift2) {
    /* master is running slower, move internal time forward */
    GST_WARNING_OBJECT (sink,
        "correct clock skew %" GST_STIME_FORMAT " > %" GST_STIME_FORMAT,
        GST_STIME_ARGS (sink->priv->avg_skew), GST_STIME_ARGS (mdrift2));

    if (sink->priv->avg_skew > (2 * mdrift)) {
      cexternal -= sink->priv->avg_skew;
      sink->priv->avg_skew = 0;
    } else {
      cexternal = cexternal > mdrift ? cexternal - mdrift : 0;
      sink->priv->avg_skew -= mdrift;
    }

    driftsamples = (sink->ringbuffer->spec.info.rate * mdrift) / GST_SECOND;
    last_align = sink->priv->last_align;

    /* if we were aligning in the wrong direction or we aligned more than what
     * we will correct, resync */
    if (last_align < 0 || last_align > driftsamples)
      sink->next_sample = -1;

    GST_DEBUG_OBJECT (sink,
        "last_align %" G_GINT64_FORMAT " driftsamples %u, next %"
        G_GUINT64_FORMAT, last_align, driftsamples, sink->next_sample);

    gst_clock_set_calibration (sink->provided_clock, cinternal, cexternal,
        crate_num, crate_denom);
  } else if (sink->priv->avg_skew < -mdrift2) {
    /* master is running faster, move external time forwards */
    GST_WARNING_OBJECT (sink,
        "correct clock skew %" GST_STIME_FORMAT " < -%" GST_STIME_FORMAT,
        GST_STIME_ARGS (sink->priv->avg_skew), GST_STIME_ARGS (mdrift2));

    if (sink->priv->avg_skew < (2 * -mdrift)) {
      cexternal -= sink->priv->avg_skew;
      sink->priv->avg_skew = 0;
    } else {
      cexternal += mdrift;
      sink->priv->avg_skew += mdrift;
    }

    driftsamples = (sink->ringbuffer->spec.info.rate * mdrift) / GST_SECOND;
    last_align = sink->priv->last_align;

    /* if we were aligning in the wrong direction or we aligned more than what
     * we will correct, resync */
    if (last_align > 0 || -last_align > driftsamples)
      sink->next_sample = -1;

    GST_DEBUG_OBJECT (sink,
        "last_align %" G_GINT64_FORMAT " driftsamples %u, next %"
        G_GUINT64_FORMAT, last_align, driftsamples, sink->next_sample);

    gst_clock_set_calibration (sink->provided_clock, cinternal, cexternal,
        crate_num, crate_denom);
  }

  /* convert, ignoring speed */
  render_start = clock_convert_external (render_start, cinternal, cexternal,
      crate_num, crate_denom);
  render_stop = clock_convert_external (render_stop, cinternal, cexternal,
      crate_num, crate_denom);

  *srender_start = render_start;
  *srender_stop = render_stop;
}

/* apply the clock offset but do no slaving otherwise */
static void
gst_audio_base_sink_none_slaving (GstAudioBaseSink * sink,
    GstClockTime render_start, GstClockTime render_stop,
    GstClockTime * srender_start, GstClockTime * srender_stop)
{
  GstClockTime cinternal, cexternal, crate_num, crate_denom;

  /* get calibration parameters to compensate for offsets */
  gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
      &crate_num, &crate_denom);

  /* convert, ignoring speed */
  render_start = clock_convert_external (render_start, cinternal, cexternal,
      crate_num, crate_denom);
  render_stop = clock_convert_external (render_stop, cinternal, cexternal,
      crate_num, crate_denom);

  *srender_start = render_start;
  *srender_stop = render_stop;
}

/* converts render_start and render_stop to their slaved values */
static void
gst_audio_base_sink_handle_slaving (GstAudioBaseSink * sink,
    GstClockTime render_start, GstClockTime render_stop,
    GstClockTime * srender_start, GstClockTime * srender_stop)
{
  switch (sink->priv->slave_method) {
    case GST_AUDIO_BASE_SINK_SLAVE_RESAMPLE:
      gst_audio_base_sink_resample_slaving (sink, render_start, render_stop,
          srender_start, srender_stop);
      break;
    case GST_AUDIO_BASE_SINK_SLAVE_SKEW:
      gst_audio_base_sink_skew_slaving (sink, render_start, render_stop,
          srender_start, srender_stop);
      break;
    case GST_AUDIO_BASE_SINK_SLAVE_NONE:
      gst_audio_base_sink_none_slaving (sink, render_start, render_stop,
          srender_start, srender_stop);
      break;
    case GST_AUDIO_BASE_SINK_SLAVE_CUSTOM:
      gst_audio_base_sink_custom_slaving (sink, render_start, render_stop,
          srender_start, srender_stop);
      break;
    default:
      g_warning ("unknown slaving method %d", sink->priv->slave_method);
      break;
  }
}

/* must be called with LOCK */
static GstFlowReturn
gst_audio_base_sink_sync_latency (GstBaseSink * bsink, GstMiniObject * obj)
{
  GstClock *clock;
  GstClockReturn status;
  GstClockTime time, render_delay;
  GstFlowReturn ret;
  GstAudioBaseSink *sink;
  GstClockTime itime, etime;
  GstClockTime rate_num, rate_denom;
  GstClockTimeDiff jitter;

  sink = GST_AUDIO_BASE_SINK (bsink);

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

  /* we provided the global clock, don't need to do anything special */
  if (clock == sink->provided_clock)
    goto no_slaving;

  GST_OBJECT_UNLOCK (sink);

  do {
    GST_DEBUG_OBJECT (sink, "checking preroll");

    ret = gst_base_sink_do_preroll (bsink, obj);
    if (ret != GST_FLOW_OK)
      goto flushing;

    GST_OBJECT_LOCK (sink);
    time = sink->priv->us_latency;
    GST_OBJECT_UNLOCK (sink);

    /* Renderdelay is added onto our own latency, and needs
     * to be subtracted as well */
    render_delay = gst_base_sink_get_render_delay (bsink);

    if (G_LIKELY (time > render_delay))
      time -= render_delay;
    else
      time = 0;

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

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

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

    /* 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 (bsink->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, "latency synced");

  /* We might need to take the object lock within gst_audio_clock_get_time(),
   * so call that before we take it again */
  itime = gst_audio_clock_get_time (GST_AUDIO_CLOCK (sink->provided_clock));
  itime =
      gst_audio_clock_adjust (GST_AUDIO_CLOCK (sink->provided_clock), itime);

  GST_OBJECT_LOCK (sink);

  /* when we prerolled in time, we can accurately set the calibration,
   * our internal clock should exactly have been the latency (== the running
   * time of the external clock) */
  etime = GST_ELEMENT_CAST (sink)->base_time + time;

  if (status == GST_CLOCK_EARLY) {
    /* when we prerolled late, we have to take into account the lateness */
    GST_DEBUG_OBJECT (sink, "late preroll, adding jitter");
    etime += jitter;
  }

  /* start ringbuffer so we can start slaving right away when we need to */
  gst_audio_base_sink_force_start (sink);

  GST_DEBUG_OBJECT (sink,
      "internal time: %" GST_TIME_FORMAT " external time: %" GST_TIME_FORMAT,
      GST_TIME_ARGS (itime), GST_TIME_ARGS (etime));

  /* copy the original calibrated rate but update the internal and external
   * times. */
  gst_clock_get_calibration (sink->provided_clock, NULL, NULL, &rate_num,
      &rate_denom);
  gst_clock_set_calibration (sink->provided_clock, itime, etime,
      rate_num, rate_denom);

  switch (sink->priv->slave_method) {
    case GST_AUDIO_BASE_SINK_SLAVE_RESAMPLE:
      /* only set as master when we are resampling */
      GST_DEBUG_OBJECT (sink, "Setting clock as master");
      gst_clock_set_master (sink->provided_clock, clock);
      break;
    case GST_AUDIO_BASE_SINK_SLAVE_SKEW:
    case GST_AUDIO_BASE_SINK_SLAVE_NONE:
    case GST_AUDIO_BASE_SINK_SLAVE_CUSTOM:
    default:
      break;
  }

  gst_audio_base_sink_reset_sync (sink);

  gst_audio_base_sink_custom_cb_report_discont (sink,
      GST_AUDIO_BASE_SINK_DISCONT_REASON_SYNC_LATENCY);

  return GST_FLOW_OK;

  /* ERRORS */
no_clock:
  {
    GST_DEBUG_OBJECT (sink, "we have no clock");
    return GST_FLOW_OK;
  }
no_slaving:
  {
    GST_DEBUG_OBJECT (sink, "we are not slaved");
    return GST_FLOW_OK;
  }
flushing:
  {
    GST_DEBUG_OBJECT (sink, "we are flushing");
    GST_OBJECT_LOCK (sink);
    return GST_FLOW_FLUSHING;
  }
}

static gint64
gst_audio_base_sink_get_alignment (GstAudioBaseSink * sink,
    GstClockTime sample_offset)
{
  GstAudioRingBuffer *ringbuf = sink->ringbuffer;
  gint64 align;
  gint64 sample_diff;
  gint64 max_sample_diff;
  gint segdone = g_atomic_int_get (&ringbuf->segdone) - ringbuf->segbase;
  gint64 samples_done = segdone * (gint64) ringbuf->samples_per_seg;
  gint64 headroom = sample_offset - samples_done;
  gboolean allow_align = TRUE;
  gboolean discont = FALSE;
  gint rate;

  /* now try to align the sample to the previous one. */

  /* calc align with previous sample and determine how big the
   * difference is. */
  align = sink->next_sample - sample_offset;
  sample_diff = ABS (align);

  /* calculate the max allowed drift in units of samples. */
  rate = GST_AUDIO_INFO_RATE (&ringbuf->spec.info);
  max_sample_diff = gst_util_uint64_scale_int (sink->priv->alignment_threshold,
      rate, GST_SECOND);

  /* don't align if it means writing behind the read-segment */
  if (sample_diff > headroom && align < 0)
    allow_align = FALSE;

  if (G_UNLIKELY (sample_diff >= max_sample_diff)) {
    /* wait before deciding to make a discontinuity */
    if (sink->priv->discont_wait > 0) {
      GstClockTime time = gst_util_uint64_scale_int (sample_offset,
          GST_SECOND, rate);
      if (sink->priv->discont_time == -1) {
        /* discont candidate */
        sink->priv->discont_time = time;
      } else if (time - sink->priv->discont_time >= sink->priv->discont_wait) {
        /* discont_wait expired, discontinuity detected */
        discont = TRUE;
        sink->priv->discont_time = -1;
      }
    } else {
      discont = TRUE;
    }
  } else if (G_UNLIKELY (sink->priv->discont_time != -1)) {
    /* we have had a discont, but are now back on track! */
    sink->priv->discont_time = -1;
  }

  if (G_LIKELY (!discont && allow_align)) {
    GST_DEBUG_OBJECT (sink,
        "align with prev sample, ABS (%" G_GINT64_FORMAT ") < %"
        G_GINT64_FORMAT, align, max_sample_diff);
  } else {
    gint64 diff_s G_GNUC_UNUSED;

    /* calculate sample diff in seconds for error message */
    diff_s = gst_util_uint64_scale_int (sample_diff, GST_SECOND, rate);

    /* timestamps drifted apart from previous samples too much, we need to
     * resync. We log this as an element warning. */
    GST_WARNING_OBJECT (sink,
        "Unexpected discontinuity in audio timestamps of "
        "%s%" GST_TIME_FORMAT ", resyncing",
        sample_offset > sink->next_sample ? "+" : "-", GST_TIME_ARGS (diff_s));
    align = 0;

    gst_audio_base_sink_custom_cb_report_discont (sink,
        GST_AUDIO_BASE_SINK_DISCONT_REASON_ALIGNMENT);
  }

  return align;
}

static GstFlowReturn
gst_audio_base_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{
  GstClockTime time, stop, render_start, render_stop, sample_offset;
  GstClockTimeDiff sync_offset, ts_offset;
  GstAudioBaseSinkClass *bclass;
  GstAudioBaseSink *sink;
  GstAudioRingBuffer *ringbuf;
  gint64 diff, align;
  guint64 ctime, cstop;
  gsize offset;
  GstMapInfo info;
  gsize size;
  guint samples, written;
  gint bpf, rate;
  gint accum;
  gint out_samples;
  GstClockTime base_time, render_delay, latency;
  GstClock *clock;
  gboolean sync, slaved, align_next;
  GstFlowReturn ret;
  GstSegment clip_seg;
  gint64 time_offset;
  GstBuffer *out = NULL;

  sink = GST_AUDIO_BASE_SINK (bsink);
  bclass = GST_AUDIO_BASE_SINK_GET_CLASS (sink);

  ringbuf = sink->ringbuffer;

  /* can't do anything when we don't have the device */
  if (G_UNLIKELY (!gst_audio_ring_buffer_is_acquired (ringbuf)))
    goto wrong_state;

  /* Wait for upstream latency before starting the ringbuffer, we do this so
   * that we can align the first sample of the ringbuffer to the base_time +
   * latency. */
  GST_OBJECT_LOCK (sink);
  base_time = GST_ELEMENT_CAST (sink)->base_time;
  if (G_UNLIKELY (sink->priv->sync_latency)) {
    ret = gst_audio_base_sink_sync_latency (bsink, GST_MINI_OBJECT_CAST (buf));
    GST_OBJECT_UNLOCK (sink);
    if (G_UNLIKELY (ret != GST_FLOW_OK))
      goto sync_latency_failed;
    /* only do this once until we are set back to PLAYING */
    sink->priv->sync_latency = FALSE;
  } else {
    GST_OBJECT_UNLOCK (sink);
  }

  /* Before we go on, let's see if we need to payload the data. If yes, we also
   * need to unref the output buffer before leaving. */
  if (bclass->payload) {
    out = bclass->payload (sink, buf);

    if (!out)
      goto payload_failed;

    buf = out;
  }

  bpf = GST_AUDIO_INFO_BPF (&ringbuf->spec.info);
  rate = GST_AUDIO_INFO_RATE (&ringbuf->spec.info);

  size = gst_buffer_get_size (buf);
  if (G_UNLIKELY (size % bpf) != 0)
    goto wrong_size;

  samples = size / bpf;
  out_samples = samples;

  time = GST_BUFFER_TIMESTAMP (buf);

  /* Last ditch attempt to ensure that we only play silence if
   * we are in trickmode no-audio mode (or if a buffer is marked as a GAP)
   * by dropping the buffer contents and rendering as a gap event instead */
  if (G_UNLIKELY ((bsink->segment.flags & GST_SEGMENT_FLAG_TRICKMODE_NO_AUDIO)
          || (buf && GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)))) {
    GstClockTime duration;
    GstEvent *event;
    GstBaseSinkClass *bclass;
    GST_DEBUG_OBJECT (bsink,
        "Received GAP or ignoring audio for trickplay. Dropping contents");

    duration = gst_util_uint64_scale_int (samples, GST_SECOND, rate);
    event = gst_event_new_gap (time, duration);

    bclass = GST_BASE_SINK_GET_CLASS (bsink);
    ret = bclass->wait_event (bsink, event);
    gst_event_unref (event);

    /* Ensure we'll resync on the next buffer as if discont */
    sink->next_sample = -1;
    goto done;
  }

  GST_DEBUG_OBJECT (sink,
      "time %" GST_TIME_FORMAT ", start %"
      GST_TIME_FORMAT ", samples %u", GST_TIME_ARGS (time),
      GST_TIME_ARGS (bsink->segment.start), samples);

  offset = 0;

  /* if not valid timestamp or we can't clip or sync, try to play
   * sample ASAP */
  if (!GST_CLOCK_TIME_IS_VALID (time)) {
    render_start = gst_audio_base_sink_get_offset (sink);
    render_stop = render_start + samples;
    GST_DEBUG_OBJECT (sink, "Buffer of size %" G_GSIZE_FORMAT " has no time."
        " Using render_start=%" G_GUINT64_FORMAT, size, render_start);
    /* we don't have a start so we don't know stop either */
    stop = -1;
    goto no_align;
  }

  /* let's calc stop based on the number of samples in the buffer instead
   * of trusting the DURATION */
  stop = time + gst_util_uint64_scale_int (samples, GST_SECOND, rate);

  /* prepare the clipping segment. Since we will be subtracting ts-offset and
   * device-delay later we scale the start and stop with those values so that we
   * can correctly clip them */
  clip_seg.format = GST_FORMAT_TIME;
  clip_seg.start = bsink->segment.start;
  clip_seg.stop = bsink->segment.stop;
  clip_seg.duration = -1;

  /* the sync offset is the combination of ts-offset and device-delay */
  latency = gst_base_sink_get_latency (bsink);
  ts_offset = gst_base_sink_get_ts_offset (bsink);
  render_delay = gst_base_sink_get_render_delay (bsink);
  sync_offset = ts_offset - render_delay + latency;

  GST_DEBUG_OBJECT (sink,
      "sync-offset %" GST_STIME_FORMAT ", render-delay %" GST_TIME_FORMAT
      ", ts-offset %" GST_STIME_FORMAT, GST_STIME_ARGS (sync_offset),
      GST_TIME_ARGS (render_delay), GST_STIME_ARGS (ts_offset));

  /* compensate for ts-offset and device-delay when negative we need to
   * clip. */
  if (G_UNLIKELY (sync_offset < 0)) {
    clip_seg.start += -sync_offset;
    if (clip_seg.stop != -1)
      clip_seg.stop += -sync_offset;
  }

  /* samples should be rendered based on their timestamp. All samples
   * arriving before the segment.start or after segment.stop are to be
   * thrown away. All samples should also be clipped to the segment
   * boundaries */
  if (G_UNLIKELY (!gst_segment_clip (&clip_seg, GST_FORMAT_TIME, time, stop,
              &ctime, &cstop)))
    goto out_of_segment;

  /* see if some clipping happened */
  diff = ctime - time;
  if (G_UNLIKELY (diff > 0)) {
    /* bring clipped time to samples */
    diff = gst_util_uint64_scale_int (diff, rate, GST_SECOND);
    GST_DEBUG_OBJECT (sink, "clipping start to %" GST_TIME_FORMAT " %"
        G_GUINT64_FORMAT " samples", GST_TIME_ARGS (ctime), diff);
    samples -= diff;
    offset += diff * bpf;
    time = ctime;
  }
  diff = stop - cstop;
  if (G_UNLIKELY (diff > 0)) {
    /* bring clipped time to samples */
    diff = gst_util_uint64_scale_int (diff, rate, GST_SECOND);
    GST_DEBUG_OBJECT (sink, "clipping stop to %" GST_TIME_FORMAT " %"
        G_GUINT64_FORMAT " samples", GST_TIME_ARGS (cstop), diff);
    samples -= diff;
    stop = cstop;
  }

  /* figure out how to sync */
  if (G_LIKELY ((clock = GST_ELEMENT_CLOCK (bsink))))
    sync = bsink->sync;
  else
    sync = FALSE;

  if (G_UNLIKELY (!sync)) {
    /* no sync needed, play sample ASAP */
    render_start = gst_audio_base_sink_get_offset (sink);
    render_stop = render_start + samples;
    GST_DEBUG_OBJECT (sink,
        "no sync needed. Using render_start=%" G_GUINT64_FORMAT, render_start);
    goto no_align;
  }

  /* bring buffer start and stop times to running time */
  render_start =
      gst_segment_to_running_time (&bsink->segment, GST_FORMAT_TIME, time);
  render_stop =
      gst_segment_to_running_time (&bsink->segment, GST_FORMAT_TIME, stop);

  GST_DEBUG_OBJECT (sink,
      "running: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
      GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));

  /* store the time of the last sample, we'll use this to perform sync on the
   * last sample when draining the buffer */
  if (G_LIKELY (bsink->segment.rate >= 0.0)) {
    sink->priv->eos_time = render_stop;
  } else {
    sink->priv->eos_time = render_start;
  }

  if (G_UNLIKELY (sync_offset != 0)) {
    /* compensate for ts-offset and delay. We know this will not underflow
     * because we clipped above. */
    GST_DEBUG_OBJECT (sink,
        "compensating for sync-offset %" GST_TIME_FORMAT,
        GST_TIME_ARGS (sync_offset));
    render_start += sync_offset;
    render_stop += sync_offset;
  }

  if (base_time != 0) {
    GST_DEBUG_OBJECT (sink, "adding base_time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (base_time));

    /* add base time to sync against the clock */
    render_start += base_time;
    render_stop += base_time;
  }

  if (G_UNLIKELY ((slaved = (clock != sink->provided_clock)))) {
    /* handle clock slaving */
    gst_audio_base_sink_handle_slaving (sink, render_start, render_stop,
        &render_start, &render_stop);
  } else {
    /* no slaving needed but we need to adapt to the clock calibration
     * parameters */
    gst_audio_base_sink_none_slaving (sink, render_start, render_stop,
        &render_start, &render_stop);
  }

  GST_DEBUG_OBJECT (sink,
      "final timestamps: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
      GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));

  /* bring to position in the ringbuffer */
  time_offset = GST_AUDIO_CLOCK_CAST (sink->provided_clock)->time_offset;

  if (G_UNLIKELY (time_offset != 0)) {
    GST_DEBUG_OBJECT (sink,
        "apply time offset %" GST_TIME_FORMAT, GST_TIME_ARGS (time_offset));

    if (render_start > time_offset)
      render_start -= time_offset;
    else
      render_start = 0;
    if (render_stop > time_offset)
      render_stop -= time_offset;
    else
      render_stop = 0;
  }

  /* in some clock slaving cases, all late samples end up at 0 first,
   * and subsequent ones align with that until threshold exceeded,
   * and then sync back to 0 and so on, so avoid that altogether */
  if (G_UNLIKELY (render_start == 0 && render_stop == 0))
    goto too_late;

  /* and bring the time to the rate corrected offset in the buffer */
  render_start = gst_util_uint64_scale_int (render_start, rate, GST_SECOND);
  render_stop = gst_util_uint64_scale_int (render_stop, rate, GST_SECOND);

  /* If the slaving got us an interval spanning 0, render_start will
     have been set to 0. So if render_start is 0, we check whether
     render_stop is set to contain all samples. If not, we need to
     drop samples to match. */
  if (render_start == 0) {
    guint nsamples = render_stop - render_start;
    if (nsamples < samples) {
      guint diff;

      diff = samples - nsamples;
      GST_DEBUG_OBJECT (bsink, "Clipped start: %u/%u samples", nsamples,
          samples);
      samples -= diff;
      offset += diff * bpf;
    }
  }

  /* positive playback rate, first sample is render_start, negative rate, first
   * sample is render_stop. When no rate conversion is active, render exactly
   * the amount of input samples to avoid aligning to rounding errors. */
  if (G_LIKELY (bsink->segment.rate >= 0.0)) {
    sample_offset = render_start;
    if (G_LIKELY (bsink->segment.rate == 1.0))
      render_stop = sample_offset + samples;
  } else {
    sample_offset = render_stop;
    if (bsink->segment.rate == -1.0)
      render_start = sample_offset + samples;
  }

  /* always resync after a discont */
  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT) ||
          GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_RESYNC))) {
    GST_DEBUG_OBJECT (sink, "resync after discont/resync");
    goto no_align;
  }

  /* resync when we don't know what to align the sample with */
  if (G_UNLIKELY (sink->next_sample == -1)) {
    GST_DEBUG_OBJECT (sink,
        "no align possible: no previous sample position known");
    goto no_align;
  }

  align = gst_audio_base_sink_get_alignment (sink, sample_offset);
  sink->priv->last_align = align;

  /* apply alignment */
  render_start += align;

  /* only align stop if we are not slaved to resample */
  if (G_UNLIKELY (slaved
          && sink->priv->slave_method == GST_AUDIO_BASE_SINK_SLAVE_RESAMPLE)) {
    GST_DEBUG_OBJECT (sink, "no stop time align needed: we are slaved");
    goto no_align;
  }
  render_stop += align;

no_align:
  /* number of target samples is difference between start and stop */
  out_samples = render_stop - render_start;

  /* we render the first or last sample first, depending on the rate */
  if (G_LIKELY (bsink->segment.rate >= 0.0))
    sample_offset = render_start;
  else
    sample_offset = render_stop;

  GST_DEBUG_OBJECT (sink, "rendering at %" G_GUINT64_FORMAT " %d/%d",
      sample_offset, samples, out_samples);

  /* we need to accumulate over different runs for when we get interrupted */
  accum = 0;
  align_next = TRUE;
  gst_buffer_map (buf, &info, GST_MAP_READ);
  do {
    written =
        gst_audio_ring_buffer_commit (ringbuf, &sample_offset,
        info.data + offset, samples, out_samples, &accum);

    GST_DEBUG_OBJECT (sink, "wrote %u of %u", written, samples);
    /* if we wrote all, we're done */
    if (G_LIKELY (written == samples))
      break;

    /* else something interrupted us and we wait for preroll. */
    if ((ret = gst_base_sink_wait_preroll (bsink)) != GST_FLOW_OK)
      goto stopping;

    /* if we got interrupted, we cannot assume that the next sample should
     * be aligned to this one */
    align_next = FALSE;

    /* update the output samples. FIXME, this will just skip them when pausing
     * during trick mode */
    if (out_samples > written) {
      out_samples -= written;
      accum = 0;
    } else
      break;

    samples -= written;
    offset += written * bpf;
  } while (TRUE);
  gst_buffer_unmap (buf, &info);

  if (G_LIKELY (align_next))
    sink->next_sample = sample_offset;
  else
    sink->next_sample = -1;

  GST_DEBUG_OBJECT (sink, "next sample expected at %" G_GUINT64_FORMAT,
      sink->next_sample);

  if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stop)
          && stop >= bsink->segment.stop)) {
    GST_DEBUG_OBJECT (sink,
        "start playback because we are at the end of segment");
    gst_audio_base_sink_force_start (sink);
  }

  ret = GST_FLOW_OK;

done:
  if (out)
    gst_buffer_unref (out);

  return ret;

  /* SPECIAL cases */
out_of_segment:
  {
    GST_DEBUG_OBJECT (sink,
        "dropping sample out of segment time %" GST_TIME_FORMAT ", start %"
        GST_TIME_FORMAT, GST_TIME_ARGS (time),
        GST_TIME_ARGS (bsink->segment.start));
    ret = GST_FLOW_OK;
    goto done;
  }
too_late:
  {
    GST_DEBUG_OBJECT (sink, "dropping late sample");
    ret = GST_FLOW_OK;
    goto done;
  }
  /* ERRORS */
payload_failed:
  {
    GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("failed to payload."));
    ret = GST_FLOW_ERROR;
    goto done;
  }
wrong_state:
  {
    GST_DEBUG_OBJECT (sink, "ringbuffer not negotiated");
    GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("sink not negotiated."));
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
wrong_size:
  {
    GST_DEBUG_OBJECT (sink, "wrong size");
    GST_ELEMENT_ERROR (sink, STREAM, WRONG_TYPE,
        (NULL), ("sink received buffer of wrong size."));
    ret = GST_FLOW_ERROR;
    goto done;
  }
stopping:
  {
    GST_DEBUG_OBJECT (sink, "preroll got interrupted: %d (%s)", ret,
        gst_flow_get_name (ret));
    gst_buffer_unmap (buf, &info);
    goto done;
  }
sync_latency_failed:
  {
    GST_DEBUG_OBJECT (sink, "failed waiting for latency");
    goto done;
  }
}

/**
 * gst_audio_base_sink_create_ringbuffer:
 * @sink: a #GstAudioBaseSink.
 *
 * Create and return the #GstAudioRingBuffer for @sink. This function will
 * call the ::create_ringbuffer vmethod and will set @sink as the parent of
 * the returned buffer (see gst_object_set_parent()).
 *
 * Returns: (transfer none): The new ringbuffer of @sink.
 */
GstAudioRingBuffer *
gst_audio_base_sink_create_ringbuffer (GstAudioBaseSink * sink)
{
  GstAudioBaseSinkClass *bclass;
  GstAudioRingBuffer *buffer = NULL;

  bclass = GST_AUDIO_BASE_SINK_GET_CLASS (sink);
  if (bclass->create_ringbuffer)
    buffer = bclass->create_ringbuffer (sink);

  if (buffer)
    gst_object_set_parent (GST_OBJECT (buffer), GST_OBJECT (sink));

  return buffer;
}

static void
gst_audio_base_sink_callback (GstAudioRingBuffer * rbuf, guint8 * data,
    guint len, gpointer user_data)
{
  GstBaseSink *basesink;
  GstAudioBaseSink *sink;
  GstBuffer *buf = NULL;
  GstFlowReturn ret;
  gsize size;

  basesink = GST_BASE_SINK (user_data);
  sink = GST_AUDIO_BASE_SINK (user_data);

  GST_PAD_STREAM_LOCK (basesink->sinkpad);

  /* would be nice to arrange for pad_alloc_buffer to return data -- as it is we
   * will copy twice, once into data, once into DMA */
  GST_LOG_OBJECT (basesink, "pulling %u bytes offset %" G_GUINT64_FORMAT
      " to fill audio buffer", len, basesink->offset);
  ret =
      gst_pad_pull_range (basesink->sinkpad, basesink->segment.position, len,
      &buf);

  if (ret != GST_FLOW_OK) {
    if (ret == GST_FLOW_EOS)
      goto eos;
    else
      goto error;
  }

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

  /* complete preroll and wait for PLAYING */
  ret = gst_base_sink_do_preroll (basesink, GST_MINI_OBJECT_CAST (buf));
  if (ret != GST_FLOW_OK)
    goto preroll_error;

  size = gst_buffer_get_size (buf);

  if (len != size) {
    GST_INFO_OBJECT (basesink,
        "got different size than requested from sink pad: %u"
        " != %" G_GSIZE_FORMAT, len, size);
    len = MIN (size, len);
  }

  basesink->segment.position += len;

  gst_buffer_extract (buf, 0, data, len);
  GST_BASE_SINK_PREROLL_UNLOCK (basesink);

  GST_PAD_STREAM_UNLOCK (basesink->sinkpad);

  return;

error:
  {
    GST_WARNING_OBJECT (basesink, "Got flow '%s' but can't return it: %d",
        gst_flow_get_name (ret), ret);
    gst_audio_ring_buffer_pause (rbuf);
    GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
    return;
  }
eos:
  {
    /* FIXME: this is not quite correct; we'll be called endlessly until
     * the sink gets shut down; maybe we should set a flag somewhere, or
     * set segment.stop and segment.duration to the last sample or so */
    GST_DEBUG_OBJECT (sink, "EOS");
    gst_audio_base_sink_drain (sink);
    gst_audio_ring_buffer_pause (rbuf);
    gst_element_post_message (GST_ELEMENT_CAST (sink),
        gst_message_new_eos (GST_OBJECT_CAST (sink)));
    GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
  }
flushing:
  {
    GST_DEBUG_OBJECT (sink, "we are flushing");
    gst_audio_ring_buffer_pause (rbuf);
    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
    GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
    return;
  }
preroll_error:
  {
    GST_DEBUG_OBJECT (sink, "error %s", gst_flow_get_name (ret));
    gst_audio_ring_buffer_pause (rbuf);
    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
    GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
    return;
  }
}

static gboolean
gst_audio_base_sink_activate_pull (GstBaseSink * basesink, gboolean active)
{
  gboolean ret;
  GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (basesink);

  if (active) {
    GST_DEBUG_OBJECT (basesink, "activating pull");

    gst_audio_ring_buffer_set_callback (sink->ringbuffer,
        gst_audio_base_sink_callback, sink);

    ret = gst_audio_ring_buffer_activate (sink->ringbuffer, TRUE);
  } else {
    GST_DEBUG_OBJECT (basesink, "deactivating pull");
    gst_audio_ring_buffer_set_callback (sink->ringbuffer, NULL, NULL);
    ret = gst_audio_ring_buffer_activate (sink->ringbuffer, FALSE);
  }

  return ret;
}

static GstStateChangeReturn
gst_audio_base_sink_change_state (GstElement * element,
    GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:{
      GstAudioRingBuffer *rb;

      gst_audio_clock_reset (GST_AUDIO_CLOCK (sink->provided_clock), 0);
      rb = gst_audio_base_sink_create_ringbuffer (sink);
      if (rb == NULL)
        goto create_failed;

      GST_OBJECT_LOCK (sink);
      sink->ringbuffer = rb;
      GST_OBJECT_UNLOCK (sink);

      if (!gst_audio_ring_buffer_open_device (sink->ringbuffer)) {
        GST_OBJECT_LOCK (sink);
        gst_object_unparent (GST_OBJECT_CAST (sink->ringbuffer));
        sink->ringbuffer = NULL;
        GST_OBJECT_UNLOCK (sink);
        goto open_failed;
      }
      break;
    }
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_audio_base_sink_reset_sync (sink);
      gst_audio_ring_buffer_set_flushing (sink->ringbuffer, FALSE);
      gst_audio_ring_buffer_may_start (sink->ringbuffer, FALSE);

      /* Only post clock-provide messages if this is the clock that
       * we've created. If the subclass has overriden it the subclass
       * should post this messages whenever necessary */
      if (gst_audio_base_sink_is_self_provided_clock (sink))
        gst_element_post_message (element,
            gst_message_new_clock_provide (GST_OBJECT_CAST (element),
                sink->provided_clock, TRUE));
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
    {
      gboolean eos;

      GST_OBJECT_LOCK (sink);
      GST_DEBUG_OBJECT (sink, "ringbuffer may start now");
      sink->priv->sync_latency = TRUE;
      eos = GST_BASE_SINK (sink)->eos;
      GST_OBJECT_UNLOCK (sink);

      gst_audio_ring_buffer_may_start (sink->ringbuffer, TRUE);
      if (GST_BASE_SINK_CAST (sink)->pad_mode == GST_PAD_MODE_PULL ||
          g_atomic_int_get (&sink->eos_rendering) || eos) {
        /* we always start the ringbuffer in pull mode immediatly */
        /* sync rendering on eos needs running clock,
         * and others need running clock when finished rendering eos */
        gst_audio_ring_buffer_start (sink->ringbuffer);
      }
      break;
    }
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      /* ringbuffer cannot start anymore */
      gst_audio_ring_buffer_may_start (sink->ringbuffer, FALSE);
      gst_audio_ring_buffer_pause (sink->ringbuffer);

      GST_OBJECT_LOCK (sink);
      sink->priv->sync_latency = FALSE;
      GST_OBJECT_UNLOCK (sink);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      /* Only post clock-lost messages if this is the clock that
       * we've created. If the subclass has overriden it the subclass
       * should post this messages whenever necessary */
      if (gst_audio_base_sink_is_self_provided_clock (sink))
        gst_element_post_message (element,
            gst_message_new_clock_lost (GST_OBJECT_CAST (element),
                sink->provided_clock));

      /* make sure we unblock before calling the parent state change
       * so it can grab the STREAM_LOCK */
      gst_audio_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      /* stop slaving ourselves to the master, if any */
      gst_clock_set_master (sink->provided_clock, NULL);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_audio_ring_buffer_activate (sink->ringbuffer, FALSE);
      gst_audio_ring_buffer_release (sink->ringbuffer);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      /* we release again here because the acquire happens when setting the
       * caps, which happens before we commit the state to PAUSED and thus the
       * PAUSED->READY state change (see above, where we release the ringbuffer)
       * might not be called when we get here. */
      gst_audio_ring_buffer_activate (sink->ringbuffer, FALSE);
      gst_audio_ring_buffer_release (sink->ringbuffer);
      gst_audio_ring_buffer_close_device (sink->ringbuffer);
      GST_OBJECT_LOCK (sink);
      gst_object_unparent (GST_OBJECT_CAST (sink->ringbuffer));
      sink->ringbuffer = NULL;
      GST_OBJECT_UNLOCK (sink);
      break;
    default:
      break;
  }

  return ret;

  /* ERRORS */
create_failed:
  {
    /* subclass must post a meaningful error message */
    GST_DEBUG_OBJECT (sink, "create failed");
    return GST_STATE_CHANGE_FAILURE;
  }
open_failed:
  {
    /* subclass must post a meaningful error message */
    GST_DEBUG_OBJECT (sink, "open failed");
    return GST_STATE_CHANGE_FAILURE;
  }
}
