/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
 * audioclock.c: Clock for use by audio plugins
 *
 * 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:gstaudioclock
 * @title: GstAudioClock
 * @short_description: Helper object for implementing audio clocks
 * @see_also: #GstAudioBaseSink, #GstSystemClock
 *
 * #GstAudioClock makes it easy for elements to implement a #GstClock, they
 * simply need to provide a function that returns the current clock time.
 *
 * This object is internally used to implement the clock in #GstAudioBaseSink.
 */

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

#include "gstaudioclock.h"

GST_DEBUG_CATEGORY_STATIC (gst_audio_clock_debug);
#define GST_CAT_DEFAULT gst_audio_clock_debug

static void gst_audio_clock_dispose (GObject * object);

static GstClockTime gst_audio_clock_get_internal_time (GstClock * clock);

#define parent_class gst_audio_clock_parent_class
G_DEFINE_TYPE (GstAudioClock, gst_audio_clock, GST_TYPE_SYSTEM_CLOCK);

static void
gst_audio_clock_class_init (GstAudioClockClass * klass)
{
  GstClockClass *gstclock_class;
  GObjectClass *gobject_class;

  gobject_class = (GObjectClass *) klass;
  gstclock_class = (GstClockClass *) klass;

  gobject_class->dispose = gst_audio_clock_dispose;
  gstclock_class->get_internal_time = gst_audio_clock_get_internal_time;

  GST_DEBUG_CATEGORY_INIT (gst_audio_clock_debug, "audioclock", 0,
      "audioclock");
}

static void
gst_audio_clock_init (GstAudioClock * clock)
{
  GST_DEBUG_OBJECT (clock, "init");
  clock->last_time = 0;
  clock->time_offset = 0;
  GST_OBJECT_FLAG_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER);
}

static void
gst_audio_clock_dispose (GObject * object)
{
  GstAudioClock *clock = GST_AUDIO_CLOCK (object);

  if (clock->destroy_notify && clock->user_data)
    clock->destroy_notify (clock->user_data);
  clock->destroy_notify = NULL;
  clock->user_data = NULL;

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

/**
 * gst_audio_clock_new:
 * @name: the name of the clock
 * @func: a function
 * @user_data: user data
 * @destroy_notify: #GDestroyNotify for @user_data
 *
 * Create a new #GstAudioClock instance. Whenever the clock time should be
 * calculated it will call @func with @user_data. When @func returns
 * #GST_CLOCK_TIME_NONE, the clock will return the last reported time.
 *
 * Returns: a new #GstAudioClock casted to a #GstClock.
 */
GstClock *
gst_audio_clock_new (const gchar * name, GstAudioClockGetTimeFunc func,
    gpointer user_data, GDestroyNotify destroy_notify)
{
  GstAudioClock *aclock =
      GST_AUDIO_CLOCK (g_object_new (GST_TYPE_AUDIO_CLOCK, "name", name,
          "clock-type", GST_CLOCK_TYPE_OTHER, NULL));

  aclock->func = func;
  aclock->user_data = user_data;
  aclock->destroy_notify = destroy_notify;

  return (GstClock *) aclock;
}

/**
 * gst_audio_clock_reset:
 * @clock: a #GstAudioClock
 * @time: a #GstClockTime
 *
 * Inform @clock that future calls to #GstAudioClockGetTimeFunc will return values
 * starting from @time. The clock will update an internal offset to make sure that
 * future calls to internal_time will return an increasing result as required by
 * the #GstClock object.
 */
void
gst_audio_clock_reset (GstAudioClock * clock, GstClockTime time)
{
  GstClockTimeDiff time_offset;

  if (clock->last_time >= time)
    time_offset = clock->last_time - time;
  else
    time_offset = -(time - clock->last_time);

  clock->time_offset = time_offset;

  GST_DEBUG_OBJECT (clock,
      "reset clock to %" GST_TIME_FORMAT ", last %" GST_TIME_FORMAT
      ", offset %" GST_STIME_FORMAT, GST_TIME_ARGS (time),
      GST_TIME_ARGS (clock->last_time), GST_STIME_ARGS (time_offset));
}

static GstClockTime
gst_audio_clock_func_invalid (GstClock * clock, gpointer user_data)
{
  return GST_CLOCK_TIME_NONE;
}

static GstClockTime
gst_audio_clock_get_internal_time (GstClock * clock)
{
  GstAudioClock *aclock;
  GstClockTime result;

  aclock = GST_AUDIO_CLOCK_CAST (clock);

  result = aclock->func (clock, aclock->user_data);
  if (result == GST_CLOCK_TIME_NONE) {
    result = aclock->last_time;
  } else {
    result += aclock->time_offset;
    /* clock must be increasing */
    if (aclock->last_time < result)
      aclock->last_time = result;
    else
      result = aclock->last_time;
  }

  GST_DEBUG_OBJECT (clock,
      "result %" GST_TIME_FORMAT ", last_time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (result), GST_TIME_ARGS (aclock->last_time));

  return result;
}

/**
 * gst_audio_clock_get_time:
 * @clock: a #GstAudioClock
 *
 * Report the time as returned by the #GstAudioClockGetTimeFunc without applying
 * any offsets.
 *
 * Returns: the time as reported by the time function of the audio clock
 */
GstClockTime
gst_audio_clock_get_time (GstAudioClock * clock)
{
  GstClockTime result;

  result = clock->func (GST_CLOCK_CAST (clock), clock->user_data);
  if (result == GST_CLOCK_TIME_NONE) {
    GST_DEBUG_OBJECT (clock, "no time, reuse last");
    result = clock->last_time - clock->time_offset;
  }

  GST_DEBUG_OBJECT (clock,
      "result %" GST_TIME_FORMAT ", last_time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (result), GST_TIME_ARGS (clock->last_time));

  return result;
}

/**
 * gst_audio_clock_adjust:
 * @clock: a #GstAudioClock
 * @time: a #GstClockTime
 *
 * Adjust @time with the internal offset of the audio clock.
 *
 * Returns: @time adjusted with the internal offset.
 */
GstClockTime
gst_audio_clock_adjust (GstAudioClock * clock, GstClockTime time)
{
  GstClockTime result;

  result = time + clock->time_offset;

  return result;
}

/**
 * gst_audio_clock_invalidate:
 * @clock: a #GstAudioClock
 *
 * Invalidate the clock function. Call this function when the provided
 * #GstAudioClockGetTimeFunc cannot be called anymore, for example, when the
 * user_data becomes invalid.
 *
 * After calling this function, @clock will return the last returned time for
 * the rest of its lifetime.
 */
void
gst_audio_clock_invalidate (GstAudioClock * clock)
{
  clock->func = gst_audio_clock_func_invalid;
}
