/* GStreamer
 * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
 *
 * gstaudioparse.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:element-audioparse
 *
 * Converts a byte stream into audio frames.
 */

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

/* FIXME 0.11: suppress warnings for deprecated API such as g_value_array stuff
 * for now with newer GLib versions (>= 2.31.0) */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include "gstaudioparse.h"
#include "unalignedaudio.h"

#include <string.h>

typedef enum
{
  GST_AUDIO_PARSE_FORMAT_RAW,
  GST_AUDIO_PARSE_FORMAT_MULAW,
  GST_AUDIO_PARSE_FORMAT_ALAW
} GstAudioParseFormat;

typedef enum
{
  GST_AUDIO_PARSE_ENDIANNESS_LITTLE = 1234,
  GST_AUDIO_PARSE_ENDIANNESS_BIG = 4321
} GstAudioParseEndianness;

static void gst_audio_parse_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_audio_parse_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_audio_parse_finalize (GObject * object);

static GstCaps *gst_audio_parse_get_caps (GstRawParse * rp);

static void gst_audio_parse_update_frame_size (GstAudioParse * ap);

GST_DEBUG_CATEGORY_STATIC (gst_audio_parse_debug);
#define GST_CAT_DEFAULT gst_audio_parse_debug

enum
{
  PROP_0,
  PROP_FORMAT,
  PROP_RAW_FORMAT,
  PROP_RATE,
  PROP_CHANNELS,
  PROP_INTERLEAVED,
  PROP_CHANNEL_POSITIONS,
  PROP_USE_SINK_CAPS
};

#define GST_AUDIO_PARSE_FORMAT (gst_audio_parse_format_get_type ())
static GType
gst_audio_parse_format_get_type (void)
{
  static GType audio_parse_format_type = 0;
  static const GEnumValue format_types[] = {
    {GST_AUDIO_PARSE_FORMAT_RAW, "Raw", "raw"},
    {GST_AUDIO_PARSE_FORMAT_ALAW, "A-Law", "alaw"},
    {GST_AUDIO_PARSE_FORMAT_MULAW, "\302\265-Law", "mulaw"},
    {0, NULL, NULL}
  };

  if (!audio_parse_format_type) {
    audio_parse_format_type =
        g_enum_register_static ("GstAudioParseFormat", format_types);
  }

  return audio_parse_format_type;
}


#define gst_audio_parse_parent_class parent_class
G_DEFINE_TYPE (GstAudioParse, gst_audio_parse, GST_TYPE_RAW_PARSE);

static void
gst_audio_parse_class_init (GstAudioParseClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (klass);
  GstCaps *caps;

  gobject_class->set_property = gst_audio_parse_set_property;
  gobject_class->get_property = gst_audio_parse_get_property;
  gobject_class->finalize = gst_audio_parse_finalize;

  rp_class->get_caps = gst_audio_parse_get_caps;

  g_object_class_install_property (gobject_class, PROP_FORMAT,
      g_param_spec_enum ("format", "Format",
          "Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT,
          GST_AUDIO_PARSE_FORMAT_RAW,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_RAW_FORMAT,
      g_param_spec_enum ("raw-format", "Raw Format",
          "Format of audio samples in raw stream", GST_TYPE_AUDIO_FORMAT,
          GST_AUDIO_FORMAT_S16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_RATE,
      g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream",
          1, INT_MAX, 44100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_CHANNELS,
      g_param_spec_int ("channels", "Channels",
          "Number of channels in raw stream", 1, 64, 2,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_INTERLEAVED,
      g_param_spec_boolean ("interleaved", "Interleaved Layout",
          "True if audio has interleaved layout", TRUE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_CHANNEL_POSITIONS,
      g_param_spec_value_array ("channel-positions", "Channel positions",
          "Channel positions used on the output",
          g_param_spec_enum ("channel-position", "Channel position",
              "Channel position of the n-th input",
              GST_TYPE_AUDIO_CHANNEL_POSITION,
              GST_AUDIO_CHANNEL_POSITION_NONE,
              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_USE_SINK_CAPS,
      g_param_spec_boolean ("use-sink-caps", "Use sink caps",
          "Use the sink caps for the format, only performing timestamping",
          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (gstelement_class, "Audio Parse",
      "Filter/Audio",
      "Converts stream into audio frames",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  caps = gst_caps_from_string (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL)
      ", layout = (string) { interleaved, non-interleaved }; "
      GST_UNALIGNED_RAW_AUDIO_CAPS "; "
      "audio/x-alaw, rate=(int)[1,MAX], channels=(int)[1,MAX]; "
      "audio/x-mulaw, rate=(int)[1,MAX], channels=(int)[1,MAX]");

  gst_raw_parse_class_set_src_pad_template (rp_class, caps);
  gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, TRUE);
  gst_caps_unref (caps);

  GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
      "audioparse element");
}

static void
gst_audio_parse_init (GstAudioParse * ap)
{
  ap->format = GST_AUDIO_PARSE_FORMAT_RAW;
  ap->raw_format = GST_AUDIO_FORMAT_S16;
  ap->channels = 2;
  ap->interleaved = TRUE;

  gst_audio_parse_update_frame_size (ap);
  gst_raw_parse_set_fps (GST_RAW_PARSE (ap), 44100, 1);
}

static void
gst_audio_parse_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioParse *ap = GST_AUDIO_PARSE (object);

  g_return_if_fail (!gst_raw_parse_is_negotiated (GST_RAW_PARSE (ap)));

  switch (prop_id) {
    case PROP_FORMAT:
      ap->format = g_value_get_enum (value);
      break;
    case PROP_RAW_FORMAT:
      ap->raw_format = g_value_get_enum (value);
      break;
    case PROP_RATE:
      gst_raw_parse_set_fps (GST_RAW_PARSE (ap), g_value_get_int (value), 1);
      break;
    case PROP_CHANNELS:
      ap->channels = g_value_get_int (value);
      break;
    case PROP_INTERLEAVED:
      ap->interleaved = g_value_get_boolean (value);
      break;
    case PROP_CHANNEL_POSITIONS:
      if (ap->channel_positions)
        g_value_array_free (ap->channel_positions);

      ap->channel_positions = g_value_dup_boxed (value);
      break;
    case PROP_USE_SINK_CAPS:
      ap->use_sink_caps = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  gst_audio_parse_update_frame_size (ap);
}

static void
gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstAudioParse *ap = GST_AUDIO_PARSE (object);

  switch (prop_id) {
    case PROP_FORMAT:
      g_value_set_enum (value, ap->format);
      break;
    case PROP_RAW_FORMAT:
      g_value_set_enum (value, ap->raw_format);
      break;
    case PROP_RATE:{
      gint fps_n, fps_d;

      gst_raw_parse_get_fps (GST_RAW_PARSE (ap), &fps_n, &fps_d);
      g_value_set_int (value, fps_n);
      break;
    }
    case PROP_CHANNELS:
      g_value_set_int (value, ap->channels);
      break;
    case PROP_INTERLEAVED:
      g_value_set_boolean (value, ap->interleaved);
      break;
    case PROP_CHANNEL_POSITIONS:
      g_value_set_boxed (value, ap->channel_positions);
      break;
    case PROP_USE_SINK_CAPS:
      g_value_set_boolean (value, ap->use_sink_caps);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_audio_parse_finalize (GObject * object)
{
  GstAudioParse *ap = GST_AUDIO_PARSE (object);

  if (ap->channel_positions) {
    g_value_array_free (ap->channel_positions);
    ap->channel_positions = NULL;
  }

  g_free (ap->channel_pos);
  g_free (ap->channel_order);

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

void
gst_audio_parse_update_frame_size (GstAudioParse * ap)
{
  gint framesize, width;

  switch (ap->format) {
    case GST_AUDIO_PARSE_FORMAT_ALAW:
    case GST_AUDIO_PARSE_FORMAT_MULAW:
      width = 8;
      break;
    case GST_AUDIO_PARSE_FORMAT_RAW:
    default:
    {
      GstAudioInfo info;

      gst_audio_info_init (&info);
      /* rate, etc do not really matter here */
      gst_audio_info_set_format (&info, ap->raw_format, 44100, ap->channels,
          NULL);
      width = GST_AUDIO_INFO_WIDTH (&info);
      break;
    }
  }

  framesize = (width / 8) * ap->channels;

  gst_raw_parse_set_framesize (GST_RAW_PARSE (ap), framesize);
}

static GstAudioChannelPosition *
gst_audio_parse_get_channel_positions (GValueArray * positions)
{
  gint i;
  guint channels;
  GstAudioChannelPosition *pos;

  channels = positions->n_values;
  pos = g_new (GstAudioChannelPosition, positions->n_values);

  for (i = 0; i < channels; i++) {
    GValue *v = g_value_array_get_nth (positions, i);

    pos[i] = g_value_get_enum (v);
  }

  return pos;
}

static void
gst_audio_parse_setup_channel_positions (GstAudioParse * ap)
{
  GstAudioChannelPosition *pos, *to;

  g_free (ap->channel_pos);
  g_free (ap->channel_order);
  ap->channel_pos = NULL;
  ap->channel_order = NULL;

  if (!ap->channel_positions) {
    GST_DEBUG_OBJECT (ap, "no channel positions");
    /* implicit mapping for 1- and 2-channel audio is okay */
    /* will come up with one in other cases also */
    return;
  }

  pos = gst_audio_parse_get_channel_positions (ap->channel_positions);
  if (ap->channels != ap->channel_positions->n_values ||
      !gst_audio_check_valid_channel_positions (pos, ap->channels, FALSE)) {
    GST_DEBUG_OBJECT (ap, "invalid channel position");
    g_free (pos);
    return;
  }

  /* ok, got something we can work with now */
  to = g_new (GstAudioChannelPosition, ap->channels);
  memcpy (to, pos, ap->channels * sizeof (to[0]));
  gst_audio_channel_positions_to_valid_order (to, ap->channels);

  ap->channel_pos = pos;
  ap->channel_order = to;
}

static GstCaps *
gst_audio_parse_get_caps (GstRawParse * rp)
{
  GstAudioParse *ap = GST_AUDIO_PARSE (rp);
  GstCaps *caps, *ncaps;
  GstAudioInfo info;
  gint fps_n, fps_d;
  const GValue *val;

  if (ap->use_sink_caps) {
    gint rate;
    GstCaps *caps = gst_pad_get_current_caps (rp->sinkpad);
    GstStructure *structure;

    if (!caps) {
      GST_WARNING_OBJECT (ap,
          "Sink pad has no caps, but we were asked to use its caps");
      return NULL;
    }

    /* For unaligned raw data, the output caps stay the same,
     * except that audio/x-unaligned-raw becomes audio/x-raw,
     * since audioparse aligns the sample data */
    structure = gst_caps_get_structure (caps, 0);
    if (gst_structure_has_name (structure, "audio/x-unaligned-raw")) {
      caps = gst_caps_make_writable (caps);
      structure = gst_caps_get_structure (caps, 0);
      gst_structure_set_name (structure, "audio/x-raw");
    }

    if (!gst_audio_info_from_caps (&info, caps)) {
      GST_WARNING_OBJECT (ap, "Failed to parse caps %" GST_PTR_FORMAT, caps);
      gst_caps_unref (caps);
      return NULL;
    }

    ap->format = GST_AUDIO_PARSE_FORMAT_RAW;
    ap->raw_format = GST_AUDIO_INFO_FORMAT (&info);
    ap->channels = GST_AUDIO_INFO_CHANNELS (&info);
    ap->interleaved = info.layout == GST_AUDIO_LAYOUT_INTERLEAVED;

    rate = GST_AUDIO_INFO_RATE (&info);
    gst_raw_parse_set_fps (GST_RAW_PARSE (ap), rate, 1);
    gst_audio_parse_update_frame_size (ap);

    return caps;
  }

  gst_raw_parse_get_fps (rp, &fps_n, &fps_d);
  gst_audio_parse_setup_channel_positions (ap);

  /* yes, even when format not raw */
  gst_audio_info_init (&info);
  gst_audio_info_set_format (&info, ap->raw_format, fps_n, ap->channels,
      ap->channel_order);
  info.layout = ap->interleaved ? GST_AUDIO_LAYOUT_INTERLEAVED :
      GST_AUDIO_LAYOUT_NON_INTERLEAVED;
  caps = gst_audio_info_to_caps (&info);

  switch (ap->format) {
    case GST_AUDIO_PARSE_FORMAT_RAW:
      break;
    case GST_AUDIO_PARSE_FORMAT_ALAW:
      ncaps = gst_caps_new_simple ("audio/x-alaw",
          "rate", G_TYPE_INT, fps_n,
          "channels", G_TYPE_INT, ap->channels, NULL);
      /* pick mask stuff from faked raw format */
      val = gst_structure_get_value (gst_caps_get_structure (caps, 0),
          "channel-mask");
      if (val)
        gst_caps_set_value (ncaps, "channel-mask", val);
      gst_caps_unref (caps);
      caps = ncaps;
      break;
    case GST_AUDIO_PARSE_FORMAT_MULAW:
      ncaps = gst_caps_new_simple ("audio/x-mulaw",
          "rate", G_TYPE_INT, fps_n,
          "channels", G_TYPE_INT, ap->channels, NULL);
      /* pick mask stuff from faked raw format */
      val = gst_structure_get_value (gst_caps_get_structure (caps, 0),
          "channel-mask");
      if (val)
        gst_caps_set_value (ncaps, "channel-mask", val);
      gst_caps_unref (caps);
      caps = ncaps;
      break;
    default:
      caps = gst_caps_new_empty ();
      GST_ERROR_OBJECT (rp, "unexpected format %d", ap->format);
      break;
  }

  return caps;
}
