/* GStreamer
 * Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
 *
 * gstaudiostreamalign.h:
 *
 * 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.
 */

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

#include "gstaudiostreamalign.h"

/**
 * SECTION:gstaudiostreamalign
 * @title: GstAudioStreamAlign
 * @short_description: Helper object for tracking audio stream alignment and discontinuities
 *
 * #GstAudioStreamAlign provides a helper object that helps tracking audio
 * stream alignment and discontinuities, and detects discontinuities if
 * possible.
 *
 * See gst_audio_stream_align_new() for a description of its parameters and
 * gst_audio_stream_align_process() for the details of the processing.
 */

G_DEFINE_BOXED_TYPE (GstAudioStreamAlign, gst_audio_stream_align,
    (GBoxedCopyFunc) gst_audio_stream_align_copy,
    (GBoxedFreeFunc) gst_audio_stream_align_free);

struct _GstAudioStreamAlign
{
  gint rate;
  GstClockTime alignment_threshold;
  GstClockTime discont_wait;

  /* counter to keep track of timestamps */
  guint64 next_offset;
  GstClockTime timestamp_at_discont;
  guint64 samples_since_discont;

  /* Last time we noticed a discont */
  GstClockTime discont_time;
};

/**
 * gst_audio_stream_align_new:
 * @rate: a sample rate
 * @alignment_threshold: a alignment threshold in nanoseconds
 * @discont_wait: discont wait in nanoseconds
 *
 * Allocate a new #GstAudioStreamAlign with the given configuration. All
 * processing happens according to sample rate @rate, until
 * gst_audio_discont_wait_set_rate() is called with a new @rate.
 * A negative rate can be used for reverse playback.
 *
 * @alignment_threshold gives the tolerance in nanoseconds after which a
 * timestamp difference is considered a discontinuity. Once detected,
 * @discont_wait nanoseconds have to pass without going below the threshold
 * again until the output buffer is marked as a discontinuity. These can later
 * be re-configured with gst_audio_stream_align_set_alignment_threshold() and
 * gst_audio_stream_align_set_discont_wait().
 *
 * Returns: a new #GstAudioStreamAlign. free with gst_audio_stream_align_free().
 *
 * Since: 1.14
 */
GstAudioStreamAlign *
gst_audio_stream_align_new (gint rate, GstClockTime alignment_threshold,
    GstClockTime discont_wait)
{
  GstAudioStreamAlign *align;

  g_return_val_if_fail (rate != 0, NULL);

  align = g_new0 (GstAudioStreamAlign, 1);
  align->rate = rate;
  align->alignment_threshold = alignment_threshold;
  align->discont_wait = discont_wait;

  align->timestamp_at_discont = GST_CLOCK_TIME_NONE;
  align->samples_since_discont = 0;
  gst_audio_stream_align_mark_discont (align);

  return align;
}

/**
 * gst_audio_stream_align_copy:
 * @align: a #GstAudioStreamAlign
 *
 * Copy a GstAudioStreamAlign structure.
 *
 * Returns: a new #GstAudioStreamAlign. free with gst_audio_stream_align_free.
 *
 * Since: 1.14
 */
GstAudioStreamAlign *
gst_audio_stream_align_copy (const GstAudioStreamAlign * align)
{
  GstAudioStreamAlign *copy;

  g_return_val_if_fail (align != NULL, NULL);

  copy = g_new0 (GstAudioStreamAlign, 1);
  *copy = *align;

  return copy;
}

/**
 * gst_audio_stream_align_free:
 * @align: a #GstAudioStreamAlign
 *
 * Free a GstAudioStreamAlign structure previously allocated with gst_audio_stream_align_new()
 * or gst_audio_stream_align_copy().
 *
 * Since: 1.14
 */
void
gst_audio_stream_align_free (GstAudioStreamAlign * align)
{
  g_return_if_fail (align != NULL);
  g_free (align);
}

/**
 * gst_audio_discont_set_rate:
 * @align: a #GstAudioStreamAlign
 * @rate: a new sample rate
 *
 * Sets @rate as new sample rate for the following processing. If the sample
 * rate differs this implicitely marks the next data as discontinuous.
 *
 * Since: 1.14
 */
void
gst_audio_stream_align_set_rate (GstAudioStreamAlign * align, gint rate)
{
  g_return_if_fail (align != NULL);
  g_return_if_fail (rate != 0);

  if (align->rate == rate)
    return;

  align->rate = rate;
  gst_audio_stream_align_mark_discont (align);
}

/**
 * gst_audio_discont_get_rate:
 * @align: a #GstAudioStreamAlign
 *
 * Gets the currently configured sample rate.
 *
 * Returns: The currently configured sample rate
 *
 * Since: 1.14
 */
gint
gst_audio_stream_align_get_rate (GstAudioStreamAlign * align)
{
  g_return_val_if_fail (align != NULL, 0);

  return align->rate;
}

/**
 * gst_audio_discont_set_alignment_threshold:
 * @align: a #GstAudioStreamAlign
 * @alignment_treshold: a new alignment threshold
 *
 * Sets @alignment_treshold as new alignment threshold for the following processing.
 *
 * Since: 1.14
 */
void
gst_audio_stream_align_set_alignment_threshold (GstAudioStreamAlign *
    align, GstClockTime alignment_threshold)
{
  g_return_if_fail (align != NULL);

  align->alignment_threshold = alignment_threshold;
}

/**
 * gst_audio_discont_get_alignment_threshold:
 * @align: a #GstAudioStreamAlign
 *
 * Gets the currently configured alignment threshold.
 *
 * Returns: The currently configured alignment threshold
 *
 * Since: 1.14
 */
GstClockTime
gst_audio_stream_align_get_alignment_threshold (GstAudioStreamAlign * align)
{
  g_return_val_if_fail (align != NULL, 0);

  return align->alignment_threshold;
}

/**
 * gst_audio_discont_set_discont_wait:
 * @align: a #GstAudioStreamAlign
 * @alignment_treshold: a new discont wait
 *
 * Sets @alignment_treshold as new discont wait for the following processing.
 *
 * Since: 1.14
 */
void
gst_audio_stream_align_set_discont_wait (GstAudioStreamAlign * align,
    GstClockTime discont_wait)
{
  g_return_if_fail (align != NULL);

  align->discont_wait = discont_wait;
}

/**
 * gst_audio_discont_get_discont_wait:
 * @align: a #GstAudioStreamAlign
 *
 * Gets the currently configured discont wait.
 *
 * Returns: The currently configured discont wait
 *
 * Since: 1.14
 */
GstClockTime
gst_audio_stream_align_get_discont_wait (GstAudioStreamAlign * align)
{
  g_return_val_if_fail (align != NULL, 0);

  return align->discont_wait;
}

/**
 * gst_audio_stream_align_mark_discont:
 * @align: a #GstAudioStreamAlign
 *
 * Marks the next buffer as discontinuous and resets timestamp tracking.
 *
 * Since: 1.14
 */
void
gst_audio_stream_align_mark_discont (GstAudioStreamAlign * align)
{
  g_return_if_fail (align != NULL);

  align->next_offset = -1;
  align->discont_time = GST_CLOCK_TIME_NONE;
}

/**
 * gst_audio_stream_align_get_timestamp_at_discont:
 * @align: a #GstAudioStreamAlign
 *
 * Timestamp that was passed when a discontinuity was detected, i.e. the first
 * timestamp after the discontinuity.
 *
 * Returns: The last timestamp at when a discontinuity was detected
 *
 * Since: 1.14
 */
GstClockTime
gst_audio_stream_align_get_timestamp_at_discont (GstAudioStreamAlign * align)
{
  g_return_val_if_fail (align != NULL, GST_CLOCK_TIME_NONE);

  return align->timestamp_at_discont;
}

/**
 * gst_audio_stream_align_get_samples_since_discont:
 * @align: a #GstAudioStreamAlign
 *
 * Returns the number of samples that were processed since the last
 * discontinuity was detected.
 *
 * Returns: The number of samples processed since the last discontinuity.
 *
 * Since: 1.14
 */
guint64
gst_audio_stream_align_get_samples_since_discont (GstAudioStreamAlign * align)
{
  g_return_val_if_fail (align != NULL, 0);

  return align->samples_since_discont;
}

/**
 * gst_audio_stream_align_process:
 * @align: a #GstAudioStreamAlign
 * @discont: if this data is considered to be discontinuous
 * @timestamp: a #GstClockTime of the start of the data
 * @n_samples: number of samples to process
 * @out_timestamp: (out): output timestamp of the data
 * @out_duration: (out): output duration of the data
 * @out_sample_position: (out): output sample position of the start of the data
 *
 * Processes data with @timestamp and @n_samples, and returns the output
 * timestamp, duration and sample position together with a boolean to signal
 * whether a discontinuity was detected or not. All non-discontinuous data
 * will have perfect timestamps and durations.
 *
 * A discontinuity is detected once the difference between the actual
 * timestamp and the timestamp calculated from the sample count since the last
 * discontinuity differs by more than the alignment threshold for a duration
 * longer than discont wait.
 *
 * Note: In reverse playback, every buffer is considered discontinuous in the
 * context of buffer flags because the last sample of the previous buffer is
 * discontinuous with the first sample of the current one. However for this
 * function they are only considered discontinuous in reverse playback if the
 * first sample of the previous buffer is discontinuous with the last sample
 * of the current one.
 *
 * Returns: %TRUE if a discontinuity was detected, %FALSE otherwise.
 *
 * Since: 1.14
 */
#define ABSDIFF(a, b) ((a) > (b) ? (a) - (b) : (b) - (a))
gboolean
gst_audio_stream_align_process (GstAudioStreamAlign * align,
    gboolean discont, GstClockTime timestamp, guint n_samples,
    GstClockTime * out_timestamp, GstClockTime * out_duration,
    guint64 * out_sample_position)
{
  GstClockTime start_time, end_time, duration;
  guint64 start_offset, end_offset;

  g_return_val_if_fail (align != NULL, FALSE);

  start_time = timestamp;
  start_offset =
      gst_util_uint64_scale (start_time, ABS (align->rate), GST_SECOND);

  end_offset = start_offset + n_samples;
  end_time =
      gst_util_uint64_scale_int (end_offset, GST_SECOND, ABS (align->rate));

  duration = end_time - start_time;

  if (align->next_offset == (guint64) - 1 || discont) {
    discont = TRUE;
  } else {
    guint64 diff, max_sample_diff;

    /* Check discont */
    if (align->rate > 0) {
      diff = ABSDIFF (start_offset, align->next_offset);
    } else {
      diff = ABSDIFF (end_offset, align->next_offset);
    }

    max_sample_diff =
        gst_util_uint64_scale_int (align->alignment_threshold,
        ABS (align->rate), GST_SECOND);

    /* Discont! */
    if (G_UNLIKELY (diff >= max_sample_diff)) {
      if (align->discont_wait > 0) {
        if (align->discont_time == GST_CLOCK_TIME_NONE) {
          align->discont_time = align->rate > 0 ? start_time : end_time;
        } else if ((align->rate > 0
                && ABSDIFF (start_time,
                    align->discont_time) >= align->discont_wait)
            || (align->rate < 0
                && ABSDIFF (end_time,
                    align->discont_time) >= align->discont_wait)) {
          discont = TRUE;
          align->discont_time = GST_CLOCK_TIME_NONE;
        }
      } else {
        discont = TRUE;
      }
    } else if (G_UNLIKELY (align->discont_time != GST_CLOCK_TIME_NONE)) {
      /* we have had a discont, but are now back on track! */
      align->discont_time = GST_CLOCK_TIME_NONE;
    }
  }

  if (discont) {
    /* Have discont, need resync and use the capture timestamps */
    if (align->next_offset != (guint64) - 1)
      GST_INFO ("Have discont. Expected %"
          G_GUINT64_FORMAT ", got %" G_GUINT64_FORMAT,
          align->next_offset, start_offset);
    align->next_offset = align->rate > 0 ? end_offset : start_offset;
    align->timestamp_at_discont = start_time;
    align->samples_since_discont = 0;

    /* Got a discont and adjusted, reset the discont_time marker */
    align->discont_time = GST_CLOCK_TIME_NONE;
  } else {

    /* No discont, just keep counting */
    if (align->rate > 0) {
      timestamp =
          gst_util_uint64_scale (align->next_offset, GST_SECOND,
          ABS (align->rate));

      start_offset = align->next_offset;
      align->next_offset += n_samples;

      duration =
          gst_util_uint64_scale (align->next_offset, GST_SECOND,
          ABS (align->rate)) - timestamp;
    } else {
      guint64 old_offset = align->next_offset;

      if (align->next_offset > n_samples)
        align->next_offset -= n_samples;
      else
        align->next_offset = 0;
      start_offset = align->next_offset;

      timestamp =
          gst_util_uint64_scale (align->next_offset, GST_SECOND,
          ABS (align->rate));

      duration =
          gst_util_uint64_scale (old_offset, GST_SECOND,
          ABS (align->rate)) - timestamp;
    }
  }

  align->samples_since_discont += n_samples;

  if (out_timestamp)
    *out_timestamp = timestamp;
  if (out_duration)
    *out_duration = duration;
  if (out_sample_position)
    *out_sample_position = start_offset;

  return discont;
}

#undef ABSDIFF
