/* GStreamer
 * Copyright (C) 2011 David A. Schleef <ds@schleef.org>
 *
 * 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 Street, Suite 500,
 * Boston, MA 02110-1335, USA.
 */
/**
 * SECTION:element-gstinteraudiosrc
 *
 * The interaudiosrc element is an audio source element.  It is used
 * in connection with a interaudiosink element in a different pipeline.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v interaudiosrc ! queue ! autoaudiosink
 * ]|
 * 
 * The interaudiosrc element cannot be used effectively with gst-launch-1.0,
 * as it requires a second pipeline in the application to send audio.
 * See the gstintertest.c example in the gst-plugins-bad source code for
 * more details.
 * </refsect2>
 */

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

#include "gstinteraudiosrc.h"

#include <gst/gst.h>
#include <gst/base/gstbasesrc.h>
#include <gst/audio/audio.h>

#include <string.h>

GST_DEBUG_CATEGORY_STATIC (gst_inter_audio_src_debug_category);
#define GST_CAT_DEFAULT gst_inter_audio_src_debug_category

/* prototypes */
static void gst_inter_audio_src_set_property (GObject * object,
    guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_inter_audio_src_get_property (GObject * object,
    guint property_id, GValue * value, GParamSpec * pspec);
static void gst_inter_audio_src_finalize (GObject * object);

static GstCaps *gst_inter_audio_src_get_caps (GstBaseSrc * src,
    GstCaps * filter);
static gboolean gst_inter_audio_src_set_caps (GstBaseSrc * src, GstCaps * caps);
static gboolean gst_inter_audio_src_start (GstBaseSrc * src);
static gboolean gst_inter_audio_src_stop (GstBaseSrc * src);
static void
gst_inter_audio_src_get_times (GstBaseSrc * src, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end);
static GstFlowReturn
gst_inter_audio_src_create (GstBaseSrc * src, guint64 offset, guint size,
    GstBuffer ** buf);
static gboolean gst_inter_audio_src_query (GstBaseSrc * src, GstQuery * query);
static GstCaps *gst_inter_audio_src_fixate (GstBaseSrc * src, GstCaps * caps);

enum
{
  PROP_0,
  PROP_CHANNEL,
  PROP_BUFFER_TIME,
  PROP_LATENCY_TIME,
  PROP_PERIOD_TIME
};

#define DEFAULT_CHANNEL ("default")

/* pad templates */
static GstStaticPadTemplate gst_inter_audio_src_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL)
        ", layout = (string) interleaved")
    );


/* class initialization */
#define parent_class gst_inter_audio_src_parent_class
G_DEFINE_TYPE (GstInterAudioSrc, gst_inter_audio_src, GST_TYPE_BASE_SRC);

static void
gst_inter_audio_src_class_init (GstInterAudioSrcClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstBaseSrcClass *base_src_class = GST_BASE_SRC_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_inter_audio_src_debug_category, "interaudiosrc",
      0, "debug category for interaudiosrc element");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_inter_audio_src_src_template));

  gst_element_class_set_static_metadata (element_class,
      "Internal audio source",
      "Source/Audio",
      "Virtual audio source for internal process communication",
      "David Schleef <ds@schleef.org>");

  gobject_class->set_property = gst_inter_audio_src_set_property;
  gobject_class->get_property = gst_inter_audio_src_get_property;
  gobject_class->finalize = gst_inter_audio_src_finalize;
  base_src_class->get_caps = GST_DEBUG_FUNCPTR (gst_inter_audio_src_get_caps);
  base_src_class->set_caps = GST_DEBUG_FUNCPTR (gst_inter_audio_src_set_caps);
  base_src_class->start = GST_DEBUG_FUNCPTR (gst_inter_audio_src_start);
  base_src_class->stop = GST_DEBUG_FUNCPTR (gst_inter_audio_src_stop);
  base_src_class->get_times = GST_DEBUG_FUNCPTR (gst_inter_audio_src_get_times);
  base_src_class->create = GST_DEBUG_FUNCPTR (gst_inter_audio_src_create);
  base_src_class->query = GST_DEBUG_FUNCPTR (gst_inter_audio_src_query);
  base_src_class->fixate = GST_DEBUG_FUNCPTR (gst_inter_audio_src_fixate);

  g_object_class_install_property (gobject_class, PROP_CHANNEL,
      g_param_spec_string ("channel", "Channel",
          "Channel name to match inter src and sink elements",
          DEFAULT_CHANNEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_BUFFER_TIME,
      g_param_spec_uint64 ("buffer-time", "Buffer Time",
          "Size of audio buffer", 1, G_MAXUINT64, DEFAULT_AUDIO_BUFFER_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_LATENCY_TIME,
      g_param_spec_uint64 ("latency-time", "Latency Time",
          "Latency as reported by the source",
          1, G_MAXUINT64, DEFAULT_AUDIO_LATENCY_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PERIOD_TIME,
      g_param_spec_uint64 ("period-time", "Period Time",
          "The minimum amount of data to read in each iteration",
          1, G_MAXUINT64, DEFAULT_AUDIO_PERIOD_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_inter_audio_src_init (GstInterAudioSrc * interaudiosrc)
{
  gst_base_src_set_format (GST_BASE_SRC (interaudiosrc), GST_FORMAT_TIME);
  gst_base_src_set_live (GST_BASE_SRC (interaudiosrc), TRUE);
  gst_base_src_set_blocksize (GST_BASE_SRC (interaudiosrc), -1);

  interaudiosrc->channel = g_strdup (DEFAULT_CHANNEL);
  interaudiosrc->buffer_time = DEFAULT_AUDIO_BUFFER_TIME;
  interaudiosrc->latency_time = DEFAULT_AUDIO_LATENCY_TIME;
  interaudiosrc->period_time = DEFAULT_AUDIO_PERIOD_TIME;
}

void
gst_inter_audio_src_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (object);

  switch (property_id) {
    case PROP_CHANNEL:
      g_free (interaudiosrc->channel);
      interaudiosrc->channel = g_value_dup_string (value);
      break;
    case PROP_BUFFER_TIME:
      interaudiosrc->buffer_time = g_value_get_uint64 (value);
      break;
    case PROP_LATENCY_TIME:
      interaudiosrc->latency_time = g_value_get_uint64 (value);
      break;
    case PROP_PERIOD_TIME:
      interaudiosrc->period_time = g_value_get_uint64 (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_inter_audio_src_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (object);

  switch (property_id) {
    case PROP_CHANNEL:
      g_value_set_string (value, interaudiosrc->channel);
      break;
    case PROP_BUFFER_TIME:
      g_value_set_uint64 (value, interaudiosrc->buffer_time);
      break;
    case PROP_LATENCY_TIME:
      g_value_set_uint64 (value, interaudiosrc->latency_time);
      break;
    case PROP_PERIOD_TIME:
      g_value_set_uint64 (value, interaudiosrc->period_time);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_inter_audio_src_finalize (GObject * object)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (object);

  /* clean up object here */
  g_free (interaudiosrc->channel);

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

static GstCaps *
gst_inter_audio_src_get_caps (GstBaseSrc * src, GstCaps * filter)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (src);
  GstCaps *caps;

  GST_DEBUG_OBJECT (interaudiosrc, "get_caps");

  if (!interaudiosrc->surface)
    return GST_BASE_SRC_CLASS (parent_class)->get_caps (src, filter);

  g_mutex_lock (&interaudiosrc->surface->mutex);
  if (interaudiosrc->surface->audio_info.finfo) {
    caps = gst_audio_info_to_caps (&interaudiosrc->surface->audio_info);
    if (filter) {
      GstCaps *tmp;

      tmp = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
      gst_caps_unref (caps);
      caps = tmp;
    }
  } else {
    caps = NULL;
  }
  g_mutex_unlock (&interaudiosrc->surface->mutex);

  if (caps)
    return caps;
  else
    return GST_BASE_SRC_CLASS (parent_class)->get_caps (src, filter);
}

static gboolean
gst_inter_audio_src_set_caps (GstBaseSrc * src, GstCaps * caps)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (src);

  GST_DEBUG_OBJECT (interaudiosrc, "set_caps");

  if (!gst_audio_info_from_caps (&interaudiosrc->info, caps)) {
    GST_ERROR_OBJECT (src, "Failed to parse caps %" GST_PTR_FORMAT, caps);
    return FALSE;
  }

  return TRUE;
}

static gboolean
gst_inter_audio_src_start (GstBaseSrc * src)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (src);

  GST_DEBUG_OBJECT (interaudiosrc, "start");

  interaudiosrc->surface = gst_inter_surface_get (interaudiosrc->channel);
  interaudiosrc->timestamp_offset = 0;
  interaudiosrc->n_samples = 0;

  g_mutex_lock (&interaudiosrc->surface->mutex);
  interaudiosrc->surface->audio_buffer_time = interaudiosrc->buffer_time;
  interaudiosrc->surface->audio_latency_time = interaudiosrc->latency_time;
  interaudiosrc->surface->audio_period_time = interaudiosrc->period_time;
  g_mutex_unlock (&interaudiosrc->surface->mutex);

  return TRUE;
}

static gboolean
gst_inter_audio_src_stop (GstBaseSrc * src)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (src);

  GST_DEBUG_OBJECT (interaudiosrc, "stop");

  gst_inter_surface_unref (interaudiosrc->surface);
  interaudiosrc->surface = NULL;

  return TRUE;
}

static void
gst_inter_audio_src_get_times (GstBaseSrc * src, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (src);

  GST_DEBUG_OBJECT (src, "get_times");

  /* for live sources, sync on the timestamp of the buffer */
  if (gst_base_src_is_live (src)) {
    if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
      *start = GST_BUFFER_TIMESTAMP (buffer);
      if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
        *end = *start + GST_BUFFER_DURATION (buffer);
      } else {
        if (interaudiosrc->info.rate > 0) {
          *end = *start +
              gst_util_uint64_scale_int (gst_buffer_get_size (buffer),
              GST_SECOND, interaudiosrc->info.rate * interaudiosrc->info.bpf);
        }
      }
    }
  }
}

static GstFlowReturn
gst_inter_audio_src_create (GstBaseSrc * src, guint64 offset, guint size,
    GstBuffer ** buf)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (src);
  GstCaps *caps;
  GstBuffer *buffer;
  guint n, bpf;
  guint64 period_time;
  guint64 period_samples;

  GST_DEBUG_OBJECT (interaudiosrc, "create");

  buffer = NULL;
  caps = NULL;

  g_mutex_lock (&interaudiosrc->surface->mutex);
  if (interaudiosrc->surface->audio_info.finfo) {
    if (!gst_audio_info_is_equal (&interaudiosrc->surface->audio_info,
            &interaudiosrc->info)) {
      caps = gst_audio_info_to_caps (&interaudiosrc->surface->audio_info);
      interaudiosrc->timestamp_offset +=
          gst_util_uint64_scale (interaudiosrc->n_samples, GST_SECOND,
          interaudiosrc->info.rate);
      interaudiosrc->n_samples = 0;
    }
  }

  bpf = interaudiosrc->surface->audio_info.bpf;
  period_time = interaudiosrc->surface->audio_period_time;
  period_samples =
      gst_util_uint64_scale (period_time, interaudiosrc->info.rate, GST_SECOND);

  if (bpf > 0)
    n = gst_adapter_available (interaudiosrc->surface->audio_adapter) / bpf;
  else
    n = 0;

  if (n > period_samples)
    n = period_samples;
  if (n > 0) {
    buffer = gst_adapter_take_buffer (interaudiosrc->surface->audio_adapter,
        n * bpf);
  } else {
    buffer = gst_buffer_new ();
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_GAP);
  }
  g_mutex_unlock (&interaudiosrc->surface->mutex);

  if (caps) {
    gboolean ret = gst_base_src_set_caps (src, caps);
    gst_caps_unref (caps);
    if (!ret) {
      GST_ERROR_OBJECT (src, "Failed to set caps %" GST_PTR_FORMAT, caps);
      if (buffer)
        gst_buffer_unref (buffer);
      return GST_FLOW_NOT_NEGOTIATED;
    }
  }

  buffer = gst_buffer_make_writable (buffer);

  bpf = interaudiosrc->info.bpf;
  if (n < period_samples) {
    GstMapInfo map;
    GstMemory *mem;

    GST_DEBUG_OBJECT (interaudiosrc,
        "creating %" G_GUINT64_FORMAT " samples of silence",
        period_samples - n);
    mem = gst_allocator_alloc (NULL, (period_samples - n) * bpf, NULL);
    if (gst_memory_map (mem, &map, GST_MAP_WRITE)) {
      gst_audio_format_fill_silence (interaudiosrc->info.finfo, map.data,
          map.size);
      gst_memory_unmap (mem, &map);
    }
    gst_buffer_prepend_memory (buffer, mem);
  }
  n = period_samples;

  GST_BUFFER_OFFSET (buffer) = interaudiosrc->n_samples;
  GST_BUFFER_OFFSET_END (buffer) = interaudiosrc->n_samples + n;
  GST_BUFFER_TIMESTAMP (buffer) = interaudiosrc->timestamp_offset +
      gst_util_uint64_scale (interaudiosrc->n_samples, GST_SECOND,
      interaudiosrc->info.rate);
  GST_DEBUG_OBJECT (interaudiosrc, "create ts %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
  GST_BUFFER_DURATION (buffer) = interaudiosrc->timestamp_offset +
      gst_util_uint64_scale (interaudiosrc->n_samples + n, GST_SECOND,
      interaudiosrc->info.rate) - GST_BUFFER_TIMESTAMP (buffer);
  GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT);
  if (interaudiosrc->n_samples == 0) {
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
  }
  interaudiosrc->n_samples += n;

  *buf = buffer;

  return GST_FLOW_OK;
}

static gboolean
gst_inter_audio_src_query (GstBaseSrc * src, GstQuery * query)
{
  GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (src);
  gboolean ret;

  GST_DEBUG_OBJECT (src, "query");

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:{
      GstClockTime min_latency, max_latency;

      min_latency = interaudiosrc->latency_time;
      max_latency = interaudiosrc->buffer_time;

      GST_DEBUG_OBJECT (src,
          "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
          GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));

      gst_query_set_latency (query,
          gst_base_src_is_live (src), min_latency, max_latency);

      ret = TRUE;
      break;
    }
    default:
      ret = GST_BASE_SRC_CLASS (gst_inter_audio_src_parent_class)->query (src,
          query);
      break;
  }

  return ret;
}

static GstCaps *
gst_inter_audio_src_fixate (GstBaseSrc * src, GstCaps * caps)
{
  GstStructure *structure;

  GST_DEBUG_OBJECT (src, "fixate");

  caps = gst_caps_make_writable (caps);
  caps = gst_caps_truncate (caps);

  structure = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_string (structure, "format", GST_AUDIO_NE (S16));
  gst_structure_fixate_field_nearest_int (structure, "channels", 2);
  gst_structure_fixate_field_nearest_int (structure, "rate", 48000);
  gst_structure_fixate_field_string (structure, "layout", "interleaved");

  return caps;
}
