/* 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
 *
 * 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.
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * 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.
 * </refsect2>
 */

#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 {
        /* 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;
}
