/* GStreamer
 * Copyright (C) <2016> Carlos Rafael Giani <dv at pseudoterminal dot 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 St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-rawaudioparse
 * @title: rawaudioparse
 *
 * This element parses incoming data as raw audio samples and timestamps it.
 * It also handles seek queries in said raw audio data, and ensures that output
 * buffers contain an integer number of samples, even if the input buffers don't.
 * For example, with sample format S16LE and 2 channels, an input buffer of 411
 * bytes contains 102.75 samples. rawaudioparse will then output 102 samples
 * (= 408 bytes) and keep the remaining 3 bytes. These will then be prepended to
 * the next input data.
 *
 * The element implements the properties and sink caps configuration as specified
 * in the #GstRawBaseParse documentation. The properties configuration can be
 * modified by using the sample-rate, num-channels, channel-positions, format,
 * and pcm-format properties.
 *
 * Currently, this parser supports raw data in a-law, mu-law, or linear PCM format.
 *
 * To facilitate operation with the unalignedaudioparse element, rawaudioparse
 * supports the "audio/x-unaligned-raw" media type. This is treated identically to
 * "audio/x-raw", except that it is used by source elements which do not guarantee
 * that the buffers they push out are timestamped and contain an integer amount of
 * samples (see the 411 bytes example above). By using a different media type, it
 * is guaranteed that unalignedaudioparse is autoplugged, making sure that the
 * autoplugged chain does not push unparsed content downstream. The source caps'
 * media type with linear PCM data is always "audio/x-raw", even if the sink caps
 * use "audio/x-unaligned-raw".
 *
 * The channel-positions property can be used to set explicit position information
 * for each channel. If the array that is passed to this property does not match
 * the number of channels indicated by num-channels, then said number of channels
 * is updated to the array length. If channel-positions is NULL, then the default
 * GStreamer positioning is used. This property is also useful for swapping left
 * and right in a stereo signal for example.
 *
 * ## Example pipelines
 * |[
 * gst-launch-1.0 souphttpsrc http://my-dlna-server/track.l16 \
 *     rawaudioparse ! audioconvert ! audioresample ! autoaudiosink
 * ]|
 *  Receive L16 data from a DLNA server, parse and timestamp it with
 * rawaudioparse, and play it. use-sink-caps is set to true since souphttpsrc
 * will set its source pad's caps to audio/x-unaligned-raw for the L16 stream.
 * |[
 * gst-launch-1.0 filesrc location=audio.raw ! rawaudioparse use-sink-caps=false \
 *         format=pcm pcm-format=s16le sample-rate=48000 num-channels=2 \
 *         audioconvert ! audioresample ! autoaudiosink
 * ]|
 *  Read raw data from a local file and parse it as PCM data with 48000 Hz sample
 * rate, signed 16 bit integer samples, and 2 channels. use-sink-caps is set to
 * false to ensure the property information is used and the parser does not expect
 * audio/x-raw or audio/x-unaligned-raw caps.
 *
 */

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

/* FIXME: GValueArray is deprecated, but there is currently no viabla alternative
 * See https://bugzilla.gnome.org/show_bug.cgi?id=667228 */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include <string.h>
#include "gstrawaudioparse.h"
#include "unalignedaudio.h"

GST_DEBUG_CATEGORY_STATIC (raw_audio_parse_debug);
#define GST_CAT_DEFAULT raw_audio_parse_debug

enum
{
  PROP_0,
  PROP_FORMAT,
  PROP_PCM_FORMAT,
  PROP_SAMPLE_RATE,
  PROP_NUM_CHANNELS,
  PROP_INTERLEAVED,
  PROP_CHANNEL_POSITIONS
};

#define DEFAULT_FORMAT         GST_RAW_AUDIO_PARSE_FORMAT_PCM
#define DEFAULT_PCM_FORMAT     GST_AUDIO_FORMAT_S16
#define DEFAULT_SAMPLE_RATE    44100
#define DEFAULT_NUM_CHANNELS   2
#define DEFAULT_INTERLEAVED    TRUE

#define GST_RAW_AUDIO_PARSE_CAPS \
  GST_AUDIO_CAPS_MAKE(GST_AUDIO_FORMATS_ALL) \
  ", layout = (string) { interleaved, non-interleaved }; " \
  "audio/x-alaw, rate = (int) [ 1, MAX ], channels = (int) [ 1, MAX ]; " \
  "audio/x-mulaw, rate = (int) [ 1, MAX ], channels = (int) [ 1, MAX ]; "

static GstStaticPadTemplate static_sink_template =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_UNALIGNED_RAW_AUDIO_CAPS "; " GST_RAW_AUDIO_PARSE_CAPS)
    );

static GstStaticPadTemplate static_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_RAW_AUDIO_PARSE_CAPS)
    );

#define gst_raw_audio_parse_parent_class parent_class
G_DEFINE_TYPE (GstRawAudioParse, gst_raw_audio_parse, GST_TYPE_RAW_BASE_PARSE);

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

static gboolean gst_raw_audio_parse_stop (GstBaseParse * parse);

static gboolean gst_raw_audio_parse_set_current_config (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config);
static GstRawBaseParseConfig
gst_raw_audio_parse_get_current_config (GstRawBaseParse * raw_base_parse);
static gboolean gst_raw_audio_parse_set_config_from_caps (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config, GstCaps * caps);
static gboolean gst_raw_audio_parse_get_caps_from_config (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config, GstCaps ** caps);
static gsize gst_raw_audio_parse_get_config_frame_size (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config);
static gboolean gst_raw_audio_parse_is_config_ready (GstRawBaseParse *
    raw_base_parse, GstRawBaseParseConfig config);
static gboolean gst_raw_audio_parse_process (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstBuffer * in_data, gsize total_num_in_bytes,
    gsize num_valid_in_bytes, GstBuffer ** processed_data);
static gboolean gst_raw_audio_parse_is_unit_format_supported (GstRawBaseParse *
    raw_base_parse, GstFormat format);
static void gst_raw_audio_parse_get_units_per_second (GstRawBaseParse *
    raw_base_parse, GstFormat format, GstRawBaseParseConfig config,
    gsize * units_per_sec_n, gsize * units_per_sec_d);
static gint gst_raw_audio_parse_get_alignment (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config);

static gboolean gst_raw_audio_parse_is_using_sink_caps (GstRawAudioParse *
    raw_audio_parse);
static GstRawAudioParseConfig
    * gst_raw_audio_parse_get_config_ptr (GstRawAudioParse * raw_audio_parse,
    GstRawBaseParseConfig config);

static void gst_raw_audio_parse_init_config (GstRawAudioParseConfig * config);
static gboolean gst_raw_audio_parse_set_config_channels (GstRawAudioParseConfig
    * config, guint num_channels, guint64 channel_mask, gboolean set_positions);
static gboolean
gst_raw_audio_parse_update_channel_reordering_flag (GstRawAudioParseConfig *
    config);
static void gst_raw_audio_parse_update_config_bpf (GstRawAudioParseConfig *
    config);
static gboolean gst_raw_audio_parse_caps_to_config (GstRawAudioParse *
    raw_audio_parse, GstCaps * caps, GstRawAudioParseConfig * config);
static gboolean gst_raw_audio_parse_config_to_caps (GstRawAudioParse *
    raw_audio_parse, GstCaps ** caps, GstRawAudioParseConfig * config);

static void
gst_raw_audio_parse_class_init (GstRawAudioParseClass * klass)
{
  GObjectClass *object_class;
  GstElementClass *element_class;
  GstBaseParseClass *baseparse_class;
  GstRawBaseParseClass *rawbaseparse_class;

  GST_DEBUG_CATEGORY_INIT (raw_audio_parse_debug, "rawaudioparse", 0,
      "rawaudioparse element");

  object_class = G_OBJECT_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);
  baseparse_class = GST_BASE_PARSE_CLASS (klass);
  rawbaseparse_class = GST_RAW_BASE_PARSE_CLASS (klass);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&static_sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&static_src_template));

  object_class->set_property =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_set_property);
  object_class->get_property =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_get_property);

  baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_raw_audio_parse_stop);

  rawbaseparse_class->set_current_config =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_set_current_config);
  rawbaseparse_class->get_current_config =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_get_current_config);
  rawbaseparse_class->set_config_from_caps =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_set_config_from_caps);
  rawbaseparse_class->get_caps_from_config =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_get_caps_from_config);
  rawbaseparse_class->get_config_frame_size =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_get_config_frame_size);
  rawbaseparse_class->is_config_ready =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_is_config_ready);
  rawbaseparse_class->process = GST_DEBUG_FUNCPTR (gst_raw_audio_parse_process);
  rawbaseparse_class->is_unit_format_supported =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_is_unit_format_supported);
  rawbaseparse_class->get_units_per_second =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_get_units_per_second);
  rawbaseparse_class->get_alignment =
      GST_DEBUG_FUNCPTR (gst_raw_audio_parse_get_alignment);

  g_object_class_install_property (object_class,
      PROP_FORMAT,
      g_param_spec_enum ("format",
          "Format",
          "Format of the raw audio stream",
          gst_raw_audio_parse_format_get_type (),
          GST_RAW_AUDIO_PARSE_FORMAT_PCM,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_PCM_FORMAT,
      g_param_spec_enum ("pcm-format",
          "PCM format",
          "Format of audio samples in PCM stream (ignored if format property is not set to pcm)",
          GST_TYPE_AUDIO_FORMAT,
          GST_RAW_AUDIO_PARSE_FORMAT_PCM,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_SAMPLE_RATE,
      g_param_spec_int ("sample-rate",
          "Sample rate",
          "Rate of audio samples in raw stream",
          1, INT_MAX,
          DEFAULT_SAMPLE_RATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_NUM_CHANNELS,
      g_param_spec_int ("num-channels",
          "Number of channels",
          "Number of channels in raw stream",
          1, INT_MAX,
          DEFAULT_NUM_CHANNELS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_class,
      PROP_INTERLEAVED,
      g_param_spec_boolean ("interleaved",
          "Interleaved layout",
          "True if audio has interleaved layout",
          DEFAULT_INTERLEAVED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
  g_object_class_install_property (object_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)
      );

  gst_element_class_set_static_metadata (element_class,
      "rawaudioparse",
      "Codec/Parser/Audio",
      "Converts unformatted data streams into timestamped raw audio frames",
      "Carlos Rafael Giani <dv@pseudoterminal.org>");
}

static void
gst_raw_audio_parse_init (GstRawAudioParse * raw_audio_parse)
{
  /* Setup configs and select which one shall be the current one from the start. */
  gst_raw_audio_parse_init_config (&(raw_audio_parse->properties_config));
  gst_raw_audio_parse_init_config (&(raw_audio_parse->sink_caps_config));
  /* As required by GstRawBaseParse, ensure that the current configuration
   * is initially set to be the properties config */
  raw_audio_parse->current_config = &(raw_audio_parse->properties_config);

  /* Properties config must be valid from the start, so set its ready value
   * to TRUE, and make sure its bpf value is valid. */
  raw_audio_parse->properties_config.ready = TRUE;
  gst_raw_audio_parse_update_config_bpf (&(raw_audio_parse->properties_config));
}

static void
gst_raw_audio_parse_set_property (GObject * object, guint prop_id,
    GValue const *value, GParamSpec * pspec)
{
  GstBaseParse *base_parse = GST_BASE_PARSE (object);
  GstRawBaseParse *raw_base_parse = GST_RAW_BASE_PARSE (object);
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (object);

  /* All properties are handled similarly:
   * - if the new value is the same as the current value, nothing is done
   * - the parser lock is held while the new value is set
   * - if the properties config is the current config, the source caps are
   *   invalidated to ensure that the code in handle_frame pushes a new CAPS
   *   event out
   * - properties that affect the bpf value call the function to update
   *   the bpf and also call gst_base_parse_set_min_frame_size() to ensure
   *   that the minimum frame size can hold 1 frame (= one sample for each
   *   channel)
   */

  switch (prop_id) {
    case PROP_FORMAT:
    {
      GstRawAudioParseFormat new_format = g_value_get_enum (value);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if (new_format != raw_audio_parse->properties_config.format) {
        raw_audio_parse->properties_config.format = new_format;
        gst_raw_audio_parse_update_config_bpf (&
            (raw_audio_parse->properties_config));

        if (!gst_raw_audio_parse_is_using_sink_caps (raw_audio_parse)) {
          gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
          gst_base_parse_set_min_frame_size (base_parse,
              raw_audio_parse->properties_config.bpf);
        }
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_PCM_FORMAT:
    {
      GstAudioFormat new_pcm_format = g_value_get_enum (value);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if (new_pcm_format != raw_audio_parse->properties_config.pcm_format) {
        raw_audio_parse->properties_config.pcm_format = new_pcm_format;
        gst_raw_audio_parse_update_config_bpf (&
            (raw_audio_parse->properties_config));

        if (!gst_raw_audio_parse_is_using_sink_caps (raw_audio_parse)) {
          gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
          gst_base_parse_set_min_frame_size (base_parse,
              raw_audio_parse->properties_config.bpf);
        }
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_SAMPLE_RATE:
    {
      guint new_sample_rate = g_value_get_int (value);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if (new_sample_rate != raw_audio_parse->properties_config.sample_rate) {
        raw_audio_parse->properties_config.sample_rate = new_sample_rate;

        if (!gst_raw_audio_parse_is_using_sink_caps (raw_audio_parse))
          gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_NUM_CHANNELS:
    {
      guint new_num_channels = g_value_get_int (value);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if (new_num_channels != raw_audio_parse->properties_config.num_channels) {
        gst_raw_audio_parse_set_config_channels (&
            (raw_audio_parse->properties_config), new_num_channels, 0, TRUE);

        raw_audio_parse->properties_config.num_channels = new_num_channels;
        gst_raw_audio_parse_update_config_bpf (&
            (raw_audio_parse->properties_config));

        if (!gst_raw_audio_parse_is_using_sink_caps (raw_audio_parse)) {
          gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
          gst_base_parse_set_min_frame_size (base_parse,
              raw_audio_parse->properties_config.bpf);
        }
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_INTERLEAVED:
    {
      gboolean new_interleaved = g_value_get_boolean (value);

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if (new_interleaved != raw_audio_parse->properties_config.interleaved) {
        raw_audio_parse->properties_config.interleaved = new_interleaved;

        if (!gst_raw_audio_parse_is_using_sink_caps (raw_audio_parse))
          gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    case PROP_CHANNEL_POSITIONS:
    {
      GValueArray *valarray = g_value_get_boxed (value);
      GstRawAudioParseConfig *config = &(raw_audio_parse->properties_config);

      /* Sanity check - reject empty arrays */
      if ((valarray != NULL) && (valarray->n_values == 0)) {
        GST_ELEMENT_ERROR (raw_audio_parse, LIBRARY, SETTINGS,
            ("channel position property holds an empty array"), (NULL));
        break;
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      if ((valarray == NULL) && (config->num_channels > 0)) {
        /* NULL value given, and number of channels is nonzero.
         * Use the default GStreamer positioning. Call
         * set_config_channels with the set_positions parameter
         * set to TRUE to ensure the position values are filled. */
        gst_raw_audio_parse_set_config_channels (&
            (raw_audio_parse->properties_config), config->num_channels, 0,
            TRUE);
      } else if (valarray != NULL) {
        /* Non-NULL value given. Make sure the channel_positions
         * array in the properties config has enough room, and that
         * the num_channels value equals the array length. Then copy
         * the values from the valarray to channel_positions, and
         * produce a copy of that array in case its channel positions
         * are not in a valid GStreamer order (to be able to apply
         * channel reordering later).
         */

        guint i;

        if (valarray->n_values != config->num_channels) {
          /* Call with set_positions == FALSE to ensure that
           * the array is properly allocated but not filled
           * (it is filled below) */
          gst_raw_audio_parse_set_config_channels (config, valarray->n_values,
              0, FALSE);
        }

        for (i = 0; i < config->num_channels; ++i) {
          GValue *val = g_value_array_get_nth (valarray, i);
          config->channel_positions[i] = g_value_get_enum (val);
        }

        gst_raw_audio_parse_update_channel_reordering_flag (config);
      }

      gst_raw_audio_parse_update_config_bpf (&
          (raw_audio_parse->properties_config));

      if (!gst_raw_audio_parse_is_using_sink_caps (raw_audio_parse)) {
        gst_raw_base_parse_invalidate_src_caps (raw_base_parse);
        gst_base_parse_set_min_frame_size (base_parse,
            raw_audio_parse->properties_config.bpf);
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;
    }

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_raw_audio_parse_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (object);

  switch (prop_id) {
    case PROP_FORMAT:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_enum (value, raw_audio_parse->properties_config.format);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_PCM_FORMAT:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_enum (value, raw_audio_parse->properties_config.pcm_format);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_SAMPLE_RATE:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_int (value, raw_audio_parse->properties_config.sample_rate);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_NUM_CHANNELS:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_int (value, raw_audio_parse->properties_config.num_channels);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_INTERLEAVED:
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);
      g_value_set_boolean (value,
          raw_audio_parse->properties_config.interleaved);
      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);
      break;

    case PROP_CHANNEL_POSITIONS:
    {
      GstRawAudioParseConfig *config;
      GValueArray *valarray;

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_LOCK (object);

      valarray = NULL;
      config = &(raw_audio_parse->properties_config);

      /* Copy channel positions into the valuearray */
      if (config->num_channels > 0) {
        guint i;
        GValue val = G_VALUE_INIT;
        g_assert (config->channel_positions);

        g_value_init (&val, GST_TYPE_AUDIO_CHANNEL_POSITION);
        valarray = g_value_array_new (config->num_channels);

        for (i = 0; i < config->num_channels; ++i) {
          g_value_set_enum (&val, config->channel_positions[i]);
          g_value_array_insert (valarray, i, &val);
        }

        g_value_unset (&val);
      }

      GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (object);

      /* Pass on ownership to the value array,
       * since we don't need it anymore */
      g_value_take_boxed (value, valarray);

      break;
    }

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_raw_audio_parse_stop (GstBaseParse * parse)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (parse);

  /* Sink caps config is not ready until caps come in.
   * We are stopping processing, the element is being reset,
   * so the config has to be un-readied.
   * (Since the properties config is not depending on caps,
   * its ready status is always TRUE.) */
  raw_audio_parse->sink_caps_config.ready = FALSE;

  return GST_BASE_PARSE_CLASS (parent_class)->stop (parse);
}

static gboolean
gst_raw_audio_parse_set_current_config (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);

  switch (config) {
    case GST_RAW_BASE_PARSE_CONFIG_PROPERTIES:
      raw_audio_parse->current_config = &(raw_audio_parse->properties_config);
      break;

    case GST_RAW_BASE_PARSE_CONFIG_SINKCAPS:
      raw_audio_parse->current_config = &(raw_audio_parse->sink_caps_config);
      break;

    default:
      g_assert_not_reached ();
  }

  return TRUE;
}

static GstRawBaseParseConfig
gst_raw_audio_parse_get_current_config (GstRawBaseParse * raw_base_parse)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
  return gst_raw_audio_parse_is_using_sink_caps (raw_audio_parse) ?
      GST_RAW_BASE_PARSE_CONFIG_SINKCAPS : GST_RAW_BASE_PARSE_CONFIG_PROPERTIES;
}

static gboolean
gst_raw_audio_parse_set_config_from_caps (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstCaps * caps)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
  return gst_raw_audio_parse_caps_to_config (raw_audio_parse, caps,
      gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config));
}

static gboolean
gst_raw_audio_parse_get_caps_from_config (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstCaps ** caps)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
  return gst_raw_audio_parse_config_to_caps (raw_audio_parse, caps,
      gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config));
}

static gsize
gst_raw_audio_parse_get_config_frame_size (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
  return gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config)->bpf;
}

static gboolean
gst_raw_audio_parse_is_config_ready (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
  return gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config)->ready;
}

static guint
round_up_pow2 (guint n)
{
  n = n - 1;
  n = n | (n >> 1);
  n = n | (n >> 2);
  n = n | (n >> 4);
  n = n | (n >> 8);
  n = n | (n >> 16);
  return n + 1;
}

static gint
gst_raw_audio_parse_get_alignment (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
  GstRawAudioParseConfig *config_ptr =
      gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config);
  gint width;

  if (config_ptr->format != GST_RAW_AUDIO_PARSE_FORMAT_PCM)
    return 1;

  width =
      GST_AUDIO_FORMAT_INFO_WIDTH (gst_audio_format_get_info
      (config_ptr->pcm_format)) / 8;
  width = GST_ROUND_UP_8 (width);
  width = round_up_pow2 (width);

  return width;
}

static gboolean
gst_raw_audio_parse_process (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstBuffer * in_data, gsize total_num_in_bytes,
    gsize num_valid_in_bytes, GstBuffer ** processed_data)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
  GstRawAudioParseConfig *config_ptr =
      gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config);

  if ((config_ptr->format == GST_RAW_AUDIO_PARSE_FORMAT_PCM)
      && config_ptr->needs_channel_reordering) {
    /* Need to reorder samples, since they are in an invalid
     * channel order. */

    GstBuffer *outbuf;

    GST_LOG_OBJECT (raw_audio_parse,
        "using %" G_GSIZE_FORMAT " bytes out of the %" G_GSIZE_FORMAT
        " bytes from the input buffer with reordering", num_valid_in_bytes,
        total_num_in_bytes);

    outbuf =
        gst_buffer_copy_region (in_data,
        GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
        GST_BUFFER_COPY_META | GST_BUFFER_COPY_MEMORY, 0, num_valid_in_bytes);

    gst_audio_buffer_reorder_channels (outbuf,
        config_ptr->pcm_format,
        config_ptr->num_channels,
        config_ptr->channel_positions, config_ptr->reordered_channel_positions);

    *processed_data = outbuf;
  } else {
    /* Nothing needs to be done with the sample data.
     * Instruct the baseparse class to just take out_size bytes
     * from the input buffer */

    GST_LOG_OBJECT (raw_audio_parse,
        "using %" G_GSIZE_FORMAT " bytes out of the %" G_GSIZE_FORMAT
        " bytes from the input buffer without reordering", num_valid_in_bytes,
        total_num_in_bytes);

    *processed_data = NULL;
  }

  return TRUE;
}

static gboolean
gst_raw_audio_parse_is_unit_format_supported (G_GNUC_UNUSED GstRawBaseParse *
    raw_base_parse, GstFormat format)
{
  switch (format) {
    case GST_FORMAT_BYTES:
    case GST_FORMAT_DEFAULT:
      return TRUE;
    default:
      return FALSE;
  }
}

static void
gst_raw_audio_parse_get_units_per_second (GstRawBaseParse * raw_base_parse,
    GstFormat format, GstRawBaseParseConfig config, gsize * units_per_sec_n,
    gsize * units_per_sec_d)
{
  GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
  GstRawAudioParseConfig *config_ptr =
      gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config);

  switch (format) {
    case GST_FORMAT_BYTES:
      *units_per_sec_n = config_ptr->sample_rate * config_ptr->bpf;
      *units_per_sec_d = 1;
      break;

    case GST_FORMAT_DEFAULT:
      *units_per_sec_n = config_ptr->sample_rate;
      *units_per_sec_d = 1;
      break;

    default:
      g_assert_not_reached ();
  }
}

static gboolean
gst_raw_audio_parse_is_using_sink_caps (GstRawAudioParse * raw_audio_parse)
{
  return raw_audio_parse->current_config ==
      &(raw_audio_parse->sink_caps_config);
}

static GstRawAudioParseConfig *
gst_raw_audio_parse_get_config_ptr (GstRawAudioParse * raw_audio_parse,
    GstRawBaseParseConfig config)
{
  g_assert (raw_audio_parse->current_config != NULL);

  switch (config) {
    case GST_RAW_BASE_PARSE_CONFIG_PROPERTIES:
      return &(raw_audio_parse->properties_config);

    case GST_RAW_BASE_PARSE_CONFIG_SINKCAPS:
      return &(raw_audio_parse->sink_caps_config);

    default:
      g_assert (raw_audio_parse->current_config != NULL);
      return raw_audio_parse->current_config;
  }
}

static void
gst_raw_audio_parse_init_config (GstRawAudioParseConfig * config)
{
  config->ready = FALSE;
  config->format = DEFAULT_FORMAT;
  config->pcm_format = DEFAULT_PCM_FORMAT;
  config->bpf = 0;
  config->sample_rate = DEFAULT_SAMPLE_RATE;
  config->num_channels = DEFAULT_NUM_CHANNELS;
  config->interleaved = DEFAULT_INTERLEAVED;
  config->needs_channel_reordering = FALSE;

  gst_raw_audio_parse_set_config_channels (config, config->num_channels, 0,
      TRUE);
}

static gboolean
gst_raw_audio_parse_set_config_channels (GstRawAudioParseConfig * config,
    guint num_channels, guint64 channel_mask, gboolean set_positions)
{
  g_assert (num_channels > 0);

  config->num_channels = num_channels;
  /* Setting this to FALSE, since initially, after setting the channels,
   * the default GStreamer channel ordering is used. */
  config->needs_channel_reordering = FALSE;

  /* Set the channel positions based on the given channel mask if set_positions
   * is set to TRUE. A channel mask of 0 signifies that a fallback mask should be
   * used for the given number of channels. */
  if (set_positions) {
    if (channel_mask == 0)
      channel_mask = gst_audio_channel_get_fallback_mask (config->num_channels);

    return gst_audio_channel_positions_from_mask (config->num_channels,
        channel_mask, config->channel_positions);
  } else {
    return TRUE;
  }
}

static gboolean
gst_raw_audio_parse_update_channel_reordering_flag (GstRawAudioParseConfig *
    config)
{
  g_assert (config->num_channels > 0);

  /* If the channel_positions array contains channel positions which are in an
   * order that conforms to the valid GStreamer order, ensure that channel
   * reordering is disabled.
   * Otherwise, if the order of the positions in the channel_positions array
   * does not conform to the GStreamer order, ensure it is enabled.
   */

  if (gst_audio_check_valid_channel_positions (config->channel_positions,
          config->num_channels, TRUE)) {

    config->needs_channel_reordering = FALSE;

    return TRUE;
  } else {
    config->needs_channel_reordering = TRUE;
    memcpy (config->reordered_channel_positions, config->channel_positions,
        sizeof (GstAudioChannelPosition) * config->num_channels);
    return
        gst_audio_channel_positions_to_valid_order
        (config->reordered_channel_positions, config->num_channels);
  }
}

static void
gst_raw_audio_parse_update_config_bpf (GstRawAudioParseConfig * config)
{
  switch (config->format) {
    case GST_RAW_AUDIO_PARSE_FORMAT_PCM:
    {
      GstAudioFormatInfo const *fmt_info =
          gst_audio_format_get_info (config->pcm_format);
      g_assert (fmt_info != NULL);

      config->bpf =
          GST_AUDIO_FORMAT_INFO_WIDTH (fmt_info) * config->num_channels / 8;

      break;
    }

    case GST_RAW_AUDIO_PARSE_FORMAT_ALAW:
    case GST_RAW_AUDIO_PARSE_FORMAT_MULAW:
      /* A-law and mu-law both use 1 byte per sample */
      config->bpf = 1 * config->num_channels;
      break;

    default:
      g_assert_not_reached ();
  }
}

static gboolean
gst_raw_audio_parse_caps_to_config (GstRawAudioParse * raw_audio_parse,
    GstCaps * caps, GstRawAudioParseConfig * config)
{
  gboolean ret = FALSE;
  GstStructure *structure;

  /* Caps might get copied, and the copy needs to be unref'd.
   * Also, the caller retains ownership over the original caps.
   * So, to make this mechanism also work with cases where the
   * caps are *not* copied, ref the original caps here first. */
  gst_caps_ref (caps);

  structure = gst_caps_get_structure (caps, 0);

  /* For unaligned raw data, the output caps stay the same,
   * except that audio/x-unaligned-raw becomes audio/x-raw,
   * since the parser aligns the sample data */
  if (gst_structure_has_name (structure, "audio/x-unaligned-raw")) {
    /* Copy the caps to be able to modify them */
    GstCaps *new_caps = gst_caps_copy (caps);
    gst_caps_unref (caps);
    caps = new_caps;

    /* Change the media type to audio/x-raw , otherwise
     * gst_audio_info_from_caps() won't work */
    structure = gst_caps_get_structure (caps, 0);
    gst_structure_set_name (structure, "audio/x-raw");
  }

  if (gst_structure_has_name (structure, "audio/x-raw")) {
    guint num_channels;
    GstAudioInfo info;
    if (!gst_audio_info_from_caps (&info, caps)) {
      GST_ERROR_OBJECT (raw_audio_parse,
          "failed to parse caps %" GST_PTR_FORMAT, (gpointer) caps);
      goto done;
    }

    num_channels = GST_AUDIO_INFO_CHANNELS (&info);

    config->format = GST_RAW_AUDIO_PARSE_FORMAT_PCM;
    config->pcm_format = GST_AUDIO_INFO_FORMAT (&info);
    config->bpf = GST_AUDIO_INFO_BPF (&info);
    config->sample_rate = GST_AUDIO_INFO_RATE (&info);
    config->interleaved =
        (GST_AUDIO_INFO_LAYOUT (&info) == GST_AUDIO_LAYOUT_INTERLEAVED);

    gst_raw_audio_parse_set_config_channels (config, num_channels, 0, FALSE);
    memcpy (config->channel_positions, &(GST_AUDIO_INFO_POSITION (&info, 0)),
        sizeof (GstAudioChannelPosition) * num_channels);
  } else if (gst_structure_has_name (structure, "audio/x-alaw")
      || gst_structure_has_name (structure, "audio/x-mulaw")) {
    gint i;
    guint64 channel_mask;
    guint num_channels;

    config->format =
        gst_structure_has_name (structure,
        "audio/x-alaw") ? GST_RAW_AUDIO_PARSE_FORMAT_ALAW :
        GST_RAW_AUDIO_PARSE_FORMAT_MULAW;

    if (!gst_structure_get_int (structure, "rate", &i)) {
      GST_ERROR_OBJECT (raw_audio_parse,
          "missing rate value in caps %" GST_PTR_FORMAT, (gpointer) caps);
      goto done;
    }
    config->sample_rate = i;

    if (!gst_structure_get_int (structure, "channels", &i)) {
      GST_ERROR_OBJECT (raw_audio_parse,
          "missing channels value in caps %" GST_PTR_FORMAT, (gpointer) caps);
      goto done;
    }
    num_channels = i;

    if (!gst_structure_get (structure, "channel-mask", GST_TYPE_BITMASK,
            &channel_mask, NULL)) {
      channel_mask = gst_audio_channel_get_fallback_mask (num_channels);
      GST_DEBUG_OBJECT (raw_audio_parse,
          "input caps have no channel mask - using fallback mask %#"
          G_GINT64_MODIFIER "x for %u channels", channel_mask, num_channels);
    }

    if (!gst_raw_audio_parse_set_config_channels (config, num_channels,
            channel_mask, TRUE)) {
      GST_ERROR_OBJECT (raw_audio_parse,
          "could not use channel mask %#" G_GINT64_MODIFIER
          "x for channel positions", channel_mask);
      goto done;
    }

    /* A-law and mu-law both use 1 byte per sample */
    config->bpf = 1 * num_channels;
  } else {
    GST_ERROR_OBJECT (raw_audio_parse,
        "caps %" GST_PTR_FORMAT " have an unsupported media type",
        (gpointer) caps);
    goto done;
  }

  ret = TRUE;

done:
  gst_caps_unref (caps);
  if (ret)
    config->ready = TRUE;
  return ret;
}

static gboolean
gst_raw_audio_parse_config_to_caps (GstRawAudioParse * raw_audio_parse,
    GstCaps ** caps, GstRawAudioParseConfig * config)
{
  gboolean ret = TRUE;
  GstAudioChannelPosition *channel_positions;

  g_assert (caps != NULL);

  if (config->bpf == 0) {
    GST_ERROR_OBJECT (raw_audio_parse,
        "cannot convert config to caps - config not filled with valid values");
    *caps = NULL;
    return FALSE;
  }

  channel_positions =
      config->needs_channel_reordering ? &(config->
      reordered_channel_positions[0]) : &(config->channel_positions[0]);

  switch (config->format) {
    case GST_RAW_AUDIO_PARSE_FORMAT_PCM:
    {
      GstAudioInfo info;
      gst_audio_info_init (&info);
      gst_audio_info_set_format (&info,
          config->pcm_format,
          config->sample_rate, config->num_channels, channel_positions);

      *caps = gst_audio_info_to_caps (&info);

      break;
    }

    case GST_RAW_AUDIO_PARSE_FORMAT_ALAW:
    case GST_RAW_AUDIO_PARSE_FORMAT_MULAW:
    {
      guint64 channel_mask;

      if (!gst_audio_channel_positions_to_mask (channel_positions,
              config->num_channels, TRUE, &channel_mask)) {
        GST_ERROR_OBJECT (raw_audio_parse, "invalid channel positions");
        ret = FALSE;
        break;
      }

      *caps = gst_caps_new_simple (
          (config->format ==
              GST_RAW_AUDIO_PARSE_FORMAT_ALAW) ? "audio/x-alaw" :
          "audio/x-mulaw", "rate", G_TYPE_INT, config->sample_rate, "channels",
          G_TYPE_INT, config->num_channels, "channel-mask", GST_TYPE_BITMASK,
          channel_mask, NULL);

      break;
    }

    default:
      g_assert_not_reached ();
      ret = FALSE;
  }

  if (!ret)
    *caps = NULL;

  return ret;
}

GType
gst_raw_audio_parse_format_get_type (void)
{
  static GType audio_parse_format_gtype = 0;
  static const GEnumValue types[] = {
    {GST_RAW_AUDIO_PARSE_FORMAT_PCM, "PCM", "pcm"},
    {GST_RAW_AUDIO_PARSE_FORMAT_ALAW, "A-Law", "alaw"},
    {GST_RAW_AUDIO_PARSE_FORMAT_MULAW, "\302\265-Law", "mulaw"},
    {0, NULL, NULL}
  };

  if (!audio_parse_format_gtype)
    audio_parse_format_gtype =
        g_enum_register_static ("GstRawAudioParseFormat", types);

  return audio_parse_format_gtype;
}
