/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) <2005> Jan Schmidt <jan@noraisin.net>
 *
 * 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.
 */
/* Element-Checklist-Version: TODO */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>

#include "gstdvdlpcmdec.h"
#include <gst/audio/audio.h>

GST_DEBUG_CATEGORY_STATIC (dvdlpcm_debug);
#define GST_CAT_DEFAULT dvdlpcm_debug

static GstStaticPadTemplate gst_dvdlpcmdec_sink_template =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-private1-lpcm; "
        "audio/x-lpcm, "
        "width = (int) { 16, 20, 24 }, "
        "rate = (int) { 32000, 44100, 48000, 96000 }, "
        "channels = (int) [ 1, 8 ], "
        "dynamic_range = (int) [ 0, 255 ], "
        "emphasis = (boolean) { TRUE, FALSE }, "
        "mute = (boolean) { TRUE, FALSE } ")
    );

static GstStaticPadTemplate gst_dvdlpcmdec_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) { S16BE, S24BE }, "
        "layout = (string) interleaved, "
        "rate = (int) { 32000, 44100, 48000, 96000 }, "
        "channels = (int) [ 1, 8 ]")
    );

/* DvdLpcmDec signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0
      /* FILL ME */
};

static void gst_dvdlpcmdec_base_init (gpointer g_class);
static void gst_dvdlpcmdec_class_init (GstDvdLpcmDecClass * klass);
static void gst_dvdlpcmdec_init (GstDvdLpcmDec * dvdlpcmdec);

static GstFlowReturn gst_dvdlpcmdec_chain_raw (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static GstFlowReturn gst_dvdlpcmdec_chain_dvd (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static gboolean gst_dvdlpcmdec_setcaps (GstPad * pad, GstCaps * caps);
static gboolean dvdlpcmdec_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static GstStateChangeReturn gst_dvdlpcmdec_change_state (GstElement * element,
    GstStateChange transition);

static GstElementClass *parent_class = NULL;

GType
gst_dvdlpcmdec_get_type (void)
{
  static GType dvdlpcmdec_type = 0;

  if (!dvdlpcmdec_type) {
    static const GTypeInfo dvdlpcmdec_info = {
      sizeof (GstDvdLpcmDecClass),
      gst_dvdlpcmdec_base_init,
      NULL,
      (GClassInitFunc) gst_dvdlpcmdec_class_init,
      NULL,
      NULL,
      sizeof (GstDvdLpcmDec),
      0,
      (GInstanceInitFunc) gst_dvdlpcmdec_init,
    };

    dvdlpcmdec_type =
        g_type_register_static (GST_TYPE_ELEMENT, "GstDvdLpcmDec",
        &dvdlpcmdec_info, 0);
  }
  return dvdlpcmdec_type;
}

static void
gst_dvdlpcmdec_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_add_static_pad_template (element_class,
      &gst_dvdlpcmdec_sink_template);
  gst_element_class_add_static_pad_template (element_class,
      &gst_dvdlpcmdec_src_template);
  gst_element_class_set_static_metadata (element_class,
      "DVD LPCM Audio decoder", "Codec/Decoder/Audio",
      "Decode DVD LPCM frames into standard PCM audio",
      "Jan Schmidt <jan@noraisin.net>, Michael Smith <msmith@fluendo.com>");
}

static void
gst_dvdlpcmdec_class_init (GstDvdLpcmDecClass * klass)
{
  GstElementClass *gstelement_class;

  gstelement_class = (GstElementClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gstelement_class->change_state = gst_dvdlpcmdec_change_state;
}

static void
gst_dvdlpcm_reset (GstDvdLpcmDec * dvdlpcmdec)
{
  gst_audio_info_init (&dvdlpcmdec->info);
  dvdlpcmdec->dynamic_range = 0;
  dvdlpcmdec->emphasis = FALSE;
  dvdlpcmdec->mute = FALSE;
  dvdlpcmdec->timestamp = GST_CLOCK_TIME_NONE;

  dvdlpcmdec->header = 0;

  gst_segment_init (&dvdlpcmdec->segment, GST_FORMAT_UNDEFINED);
}

static void
gst_dvdlpcmdec_init (GstDvdLpcmDec * dvdlpcmdec)
{
  dvdlpcmdec->sinkpad =
      gst_pad_new_from_static_template (&gst_dvdlpcmdec_sink_template, "sink");
  gst_pad_set_event_function (dvdlpcmdec->sinkpad, dvdlpcmdec_sink_event);
  gst_element_add_pad (GST_ELEMENT (dvdlpcmdec), dvdlpcmdec->sinkpad);

  dvdlpcmdec->srcpad =
      gst_pad_new_from_static_template (&gst_dvdlpcmdec_src_template, "src");
  gst_pad_use_fixed_caps (dvdlpcmdec->srcpad);
  gst_element_add_pad (GST_ELEMENT (dvdlpcmdec), dvdlpcmdec->srcpad);

  gst_dvdlpcm_reset (dvdlpcmdec);
}

static const GstAudioChannelPosition channel_positions[][8] = {
  {GST_AUDIO_CHANNEL_POSITION_MONO},
  {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
  {GST_AUDIO_CHANNEL_POSITION_INVALID},
  {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
      GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
  {GST_AUDIO_CHANNEL_POSITION_INVALID},
  {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
      GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
  {GST_AUDIO_CHANNEL_POSITION_INVALID},
  {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
      GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT},
  {GST_AUDIO_CHANNEL_POSITION_INVALID}
};

static void
gst_dvdlpcmdec_send_tags (GstDvdLpcmDec * dvdlpcmdec)
{
  GstTagList *taglist;
  guint bitrate;
  gint bpf, rate;

  bpf = GST_AUDIO_INFO_BPF (&dvdlpcmdec->info);
  rate = GST_AUDIO_INFO_RATE (&dvdlpcmdec->info);

  bitrate = bpf * 8 * rate;

  taglist = gst_tag_list_new (GST_TAG_AUDIO_CODEC, "LPCM Audio",
      GST_TAG_BITRATE, bitrate, NULL);

  gst_pad_push_event (dvdlpcmdec->srcpad, gst_event_new_tag (taglist));
}

static gboolean
gst_dvdlpcmdec_set_outcaps (GstDvdLpcmDec * dvdlpcmdec)
{
  gboolean res = TRUE;
  GstCaps *src_caps;

  /* Build caps to set on the src pad, which we know from the incoming caps */
  src_caps = gst_audio_info_to_caps (&dvdlpcmdec->info);

  res = gst_pad_set_caps (dvdlpcmdec->srcpad, src_caps);
  if (res) {
    GST_DEBUG_OBJECT (dvdlpcmdec, "Successfully set output caps: %"
        GST_PTR_FORMAT, src_caps);

    gst_dvdlpcmdec_send_tags (dvdlpcmdec);
  } else {
    GST_DEBUG_OBJECT (dvdlpcmdec, "Failed to set output caps: %"
        GST_PTR_FORMAT, src_caps);
  }

  gst_caps_unref (src_caps);

  return res;
}

static void
gst_dvdlpcmdec_update_audio_formats (GstDvdLpcmDec * dec, gint channels,
    gint rate, GstAudioFormat format)
{
  GST_DEBUG_OBJECT (dec, "got channles = %d, rate = %d, format = %d", channels,
      rate, format);

  /* Reorder the channel positions and set the default into for the audio */
  if (channels < 9
      && channel_positions[channels - 1][0] !=
      GST_AUDIO_CHANNEL_POSITION_INVALID) {
    const GstAudioChannelPosition *position;
    GstAudioChannelPosition sorted_position[8];
    guint c;

    position = channel_positions[channels - 1];
    dec->lpcm_layout = position;
    for (c = 0; c < channels; ++c)
      sorted_position[c] = position[c];
    gst_audio_channel_positions_to_valid_order (sorted_position, channels);
    gst_audio_info_set_format (&dec->info, format, rate, channels,
        sorted_position);
  } else {
    gst_audio_info_set_format (&dec->info, format, rate, channels, NULL);
  }
}

static gboolean
gst_dvdlpcmdec_setcaps (GstPad * pad, GstCaps * caps)
{
  GstStructure *structure;
  gboolean res = TRUE;
  GstDvdLpcmDec *dvdlpcmdec;
  GstAudioFormat format;
  gint rate, channels, width;

  g_return_val_if_fail (caps != NULL, FALSE);
  g_return_val_if_fail (pad != NULL, FALSE);

  dvdlpcmdec = GST_DVDLPCMDEC (gst_pad_get_parent (pad));

  structure = gst_caps_get_structure (caps, 0);

  /* If we have the DVD structured LPCM (including header) then we wait
   * for incoming data before creating the output pad caps */
  if (gst_structure_has_name (structure, "audio/x-private1-lpcm")) {
    gst_pad_set_chain_function (dvdlpcmdec->sinkpad, gst_dvdlpcmdec_chain_dvd);
    goto done;
  }

  gst_pad_set_chain_function (dvdlpcmdec->sinkpad, gst_dvdlpcmdec_chain_raw);

  res &= gst_structure_get_int (structure, "rate", &rate);
  res &= gst_structure_get_int (structure, "channels", &channels);
  res &= gst_structure_get_int (structure, "width", &width);
  res &= gst_structure_get_int (structure, "dynamic_range",
      &dvdlpcmdec->dynamic_range);
  res &= gst_structure_get_boolean (structure, "emphasis",
      &dvdlpcmdec->emphasis);
  res &= gst_structure_get_boolean (structure, "mute", &dvdlpcmdec->mute);

  if (!res)
    goto caps_parse_error;

  switch (width) {
    case 24:
    case 20:
      format = GST_AUDIO_FORMAT_S24BE;
      break;
    case 16:
      format = GST_AUDIO_FORMAT_S16BE;
      break;
    default:
      format = GST_AUDIO_FORMAT_UNKNOWN;
      break;
  }

  gst_dvdlpcmdec_update_audio_formats (dvdlpcmdec, channels, rate, format);

  dvdlpcmdec->width = width;

  res = gst_dvdlpcmdec_set_outcaps (dvdlpcmdec);

done:
  gst_object_unref (dvdlpcmdec);
  return res;

  /* ERRORS */
caps_parse_error:
  {
    GST_DEBUG_OBJECT (dvdlpcmdec, "Couldn't get parameters; missing caps?");
    gst_object_unref (dvdlpcmdec);
    return FALSE;
  }
}

static void
update_timestamps (GstDvdLpcmDec * dvdlpcmdec, GstBuffer * buf, int samples)
{
  gboolean take_buf_ts = FALSE;
  gint rate;

  rate = GST_AUDIO_INFO_RATE (&dvdlpcmdec->info);

  GST_BUFFER_DURATION (buf) = gst_util_uint64_scale (samples, GST_SECOND, rate);

  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
    if (GST_CLOCK_TIME_IS_VALID (dvdlpcmdec->timestamp)) {
      GstClockTimeDiff one_sample = GST_SECOND / rate;
      GstClockTimeDiff diff = GST_CLOCK_DIFF (GST_BUFFER_TIMESTAMP (buf),
          dvdlpcmdec->timestamp);

      if (diff > one_sample || diff < -one_sample)
        take_buf_ts = TRUE;
    } else {
      take_buf_ts = TRUE;
    }
  } else if (!GST_CLOCK_TIME_IS_VALID (dvdlpcmdec->timestamp)) {
    dvdlpcmdec->timestamp = 0;
  }

  if (take_buf_ts) {
    /* Take buffer timestamp */
    dvdlpcmdec->timestamp = GST_BUFFER_TIMESTAMP (buf);
  } else {
    GST_BUFFER_TIMESTAMP (buf) = dvdlpcmdec->timestamp;
  }

  dvdlpcmdec->timestamp += GST_BUFFER_DURATION (buf);

  GST_LOG_OBJECT (dvdlpcmdec, "Updated timestamp to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
}

static void
parse_header (GstDvdLpcmDec * dec, guint32 header)
{
  GstAudioFormat format;
  gint rate, channels, width;

  /* We don't actually use 'dynamic range', 'mute', or 'emphasis' currently,
   * but parse them out */
  dec->dynamic_range = header & 0xff;

  dec->mute = (header & 0x400000) != 0;
  dec->emphasis = (header & 0x800000) != 0;

  /* These two bits tell us the bit depth */
  switch (header & 0xC000) {
    case 0x8000:
      /* 24 bits in 3 bytes */
      format = GST_AUDIO_FORMAT_S24BE;
      width = 24;
      break;
    case 0x4000:
      /* 20 bits in 3 bytes */
      format = GST_AUDIO_FORMAT_S24BE;
      width = 20;
      break;
    default:
      format = GST_AUDIO_FORMAT_S16BE;
      width = 16;
      break;
  }

  dec->width = width;

  /* Only four sample rates supported */
  switch (header & 0x3000) {
    case 0x0000:
      rate = 48000;
      break;
    case 0x1000:
      rate = 96000;
      break;
    case 0x2000:
      rate = 44100;
      break;
    case 0x3000:
      rate = 32000;
      break;
    default:
      rate = 0;
      break;
  }

  /* And, of course, the number of channels (up to 8) */
  channels = ((header >> 8) & 0x7) + 1;

  gst_dvdlpcmdec_update_audio_formats (dec, channels, rate, format);
}

static GstFlowReturn
gst_dvdlpcmdec_chain_dvd (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstDvdLpcmDec *dvdlpcmdec;
  GstMapInfo map;
  guint8 *data;
  gsize size;
  guint first_access;
  guint32 header;
  GstBuffer *subbuf;
  GstFlowReturn ret = GST_FLOW_OK;
  gint off, len;
  gint rate, channels;

  dvdlpcmdec = GST_DVDLPCMDEC (parent);

  gst_buffer_map (buf, &map, GST_MAP_READ);
  data = map.data;
  size = map.size;

  if (size < 5)
    goto too_small;

  /* We have a 5 byte header, now.
   * The first two bytes are a (big endian) 16 bit offset into our buffer.
   * The buffer timestamp refers to this offset.
   *
   * The other three bytes are a (big endian) number in which the header is
   * encoded.
   */
  first_access = (data[0] << 8) | data[1];
  if (first_access > size)
    goto invalid_data;

  /* Don't keep the 'frame number' low 5 bits of the first byte */
  header = ((data[2] & 0xC0) << 16) | (data[3] << 8) | data[4];

  /* see if we have a new header */
  if (header != dvdlpcmdec->header) {
    parse_header (dvdlpcmdec, header);

    if (!gst_dvdlpcmdec_set_outcaps (dvdlpcmdec))
      goto negotiation_failed;

    dvdlpcmdec->header = header;
  }

  GST_LOG_OBJECT (dvdlpcmdec, "first_access %d, buffer length %" G_GSIZE_FORMAT,
      first_access, size);

  rate = GST_AUDIO_INFO_RATE (&dvdlpcmdec->info);
  channels = GST_AUDIO_INFO_CHANNELS (&dvdlpcmdec->info);

  /* After first_access, we have an additional 3 bytes of data we've parsed and
   * don't want to handle; this is included within the value of first_access.
   * So a first_access value of between 1 and 3 is just broken, we treat that
   * the same as zero. first_access == 4 means we only need to create a single
   * sub-buffer, greater than that we need to create two. */

  /* skip access unit bytes and info */
  off = 5;

  if (first_access > 4) {
    guint samples = 0;
    GstClockTime ts;

    /* length of first buffer */
    len = first_access - 4;

    GST_LOG_OBJECT (dvdlpcmdec, "Creating first sub-buffer off %d, len %d",
        off, len);

    /* see if we need a subbuffer without timestamp */
    if (off + len > size)
      goto bad_first_access;

    subbuf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, off, len);

    /* If we don't have a stored timestamp from the last packet,
     * (it's straight after a new-segment, but we have one on the
     * first access buffer, then calculate the timestamp to align
     * this buffer to just before the first_access buffer */
    if (!GST_CLOCK_TIME_IS_VALID (dvdlpcmdec->timestamp) &&
        GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
      switch (dvdlpcmdec->width) {
        case 16:
          samples = len / channels / 2;
          break;
        case 20:
          samples = (len / channels) * 2 / 5;
          break;
        case 24:
          samples = len / channels / 3;
          break;
      }
    }
    if (samples != 0) {
      ts = gst_util_uint64_scale (samples, GST_SECOND, rate);
      if (ts < GST_BUFFER_TIMESTAMP (buf))
        GST_BUFFER_TIMESTAMP (subbuf) = GST_BUFFER_TIMESTAMP (buf) - ts;
      else
        GST_BUFFER_TIMESTAMP (subbuf) = 0;
    } else {
      GST_BUFFER_TIMESTAMP (subbuf) = GST_CLOCK_TIME_NONE;
    }

    ret = gst_dvdlpcmdec_chain_raw (pad, parent, subbuf);
    if (ret != GST_FLOW_OK)
      goto done;

    /* then the buffer with new timestamp */
    off += len;
    len = size - off;

    GST_LOG_OBJECT (dvdlpcmdec, "Creating next sub-buffer off %d, len %d", off,
        len);

    if (len > 0) {
      subbuf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, off, len);
      GST_BUFFER_TIMESTAMP (subbuf) = GST_BUFFER_TIMESTAMP (buf);

      ret = gst_dvdlpcmdec_chain_raw (pad, parent, subbuf);
    }
  } else {
    GST_LOG_OBJECT (dvdlpcmdec,
        "Creating single sub-buffer off %d, len %" G_GSIZE_FORMAT, off,
        size - off);
    subbuf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, off, size - off);
    GST_BUFFER_TIMESTAMP (subbuf) = GST_BUFFER_TIMESTAMP (buf);
    ret = gst_dvdlpcmdec_chain_raw (pad, parent, subbuf);
  }

done:
  gst_buffer_unmap (buf, &map);
  gst_buffer_unref (buf);

  return ret;

  /* ERRORS */
too_small:
  {
    /* Buffer is too small */
    GST_ELEMENT_WARNING (dvdlpcmdec, STREAM, DECODE,
        ("Invalid data found parsing LPCM packet"),
        ("LPCM packet was too small. Dropping"));
    ret = GST_FLOW_OK;
    goto done;
  }
invalid_data:
  {
    GST_ELEMENT_WARNING (dvdlpcmdec, STREAM, DECODE,
        ("Invalid data found parsing LPCM packet"),
        ("LPCM packet contained invalid first access. Dropping"));
    ret = GST_FLOW_OK;
    goto done;
  }
negotiation_failed:
  {
    GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, FORMAT, (NULL),
        ("Failed to configure output format"));
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
bad_first_access:
  {
    GST_WARNING_OBJECT (pad, "Bad first_access parameter in buffer");
    GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, DECODE,
        (NULL),
        ("first_access parameter out of range: bad buffer from demuxer"));
    ret = GST_FLOW_ERROR;
    goto done;
  }
}

static GstFlowReturn
gst_dvdlpcmdec_chain_raw (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstDvdLpcmDec *dvdlpcmdec;
  gsize size;
  GstFlowReturn ret;
  guint samples = 0;
  gint rate, channels;

  dvdlpcmdec = GST_DVDLPCMDEC (parent);

  size = gst_buffer_get_size (buf);

  GST_LOG_OBJECT (dvdlpcmdec,
      "got buffer %p of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT,
      buf, size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));

  rate = GST_AUDIO_INFO_RATE (&dvdlpcmdec->info);
  channels = GST_AUDIO_INFO_CHANNELS (&dvdlpcmdec->info);

  if (rate == 0)
    goto not_negotiated;

  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
    dvdlpcmdec->timestamp = GST_BUFFER_TIMESTAMP (buf);

  /* We don't currently do anything at all regarding emphasis, mute or
   * dynamic_range - I'm not sure what they're for */
  switch (dvdlpcmdec->width) {
    case 16:
    {
      /* We can just pass 16-bits straight through intact, once we set
       * appropriate things on the buffer */
      samples = size / channels / 2;
      if (samples < 1)
        goto drop;
      buf = gst_buffer_make_writable (buf);
      break;
    }
    case 20:
    {
      /* Allocate a new buffer and copy 20-bit width to 24-bit */
      gint64 samples = size * 8 / 20;
      gint64 count = size / 10;
      gint64 i;
      GstMapInfo srcmap, destmap;
      guint8 *src;
      guint8 *dest;
      GstBuffer *outbuf;

      if (samples < 1)
        goto drop;

      outbuf = gst_buffer_new_allocate (NULL, samples * 3, NULL);
      gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);

      /* adjust samples so we can calc the new timestamp */
      samples = samples / channels;

      gst_buffer_map (buf, &srcmap, GST_MAP_READ);
      gst_buffer_map (outbuf, &destmap, GST_MAP_WRITE);
      src = srcmap.data;
      dest = destmap.data;

      /* Copy 20-bit LPCM format to 24-bit buffers, with 0x00 in the lowest
       * nibble. Note that the first 2 bytes are already correct */
      for (i = 0; i < count; i++) {
        dest[0] = src[0];
        dest[1] = src[1];
        dest[2] = src[8] & 0xf0;
        dest[3] = src[2];
        dest[4] = src[3];
        dest[5] = (src[8] & 0x0f) << 4;
        dest[6] = src[4];
        dest[7] = src[5];
        dest[8] = src[9] & 0x0f;
        dest[9] = src[6];
        dest[10] = src[7];
        dest[11] = (src[9] & 0x0f) << 4;

        src += 10;
        dest += 12;
      }
      gst_buffer_unmap (outbuf, &destmap);
      gst_buffer_unmap (buf, &srcmap);
      gst_buffer_unref (buf);
      buf = outbuf;
      break;
    }
    case 24:
    {
      /* Rearrange 24-bit LPCM format in-place. Note that the first 2
       * and last byte are already correct */
      guint count = size / 12;
      gint i;
      GstMapInfo map;
      guint8 *ptr;

      samples = size / channels / 3;

      if (samples < 1)
        goto drop;

      /* Ensure our output buffer is writable */
      buf = gst_buffer_make_writable (buf);

      gst_buffer_map (buf, &map, GST_MAP_READWRITE);
      ptr = map.data;

      for (i = 0; i < count; i++) {
        guint8 tmp;

        tmp = ptr[10];
        ptr[10] = ptr[7];
        ptr[7] = ptr[5];
        ptr[5] = ptr[9];
        ptr[9] = ptr[6];
        ptr[6] = ptr[4];
        ptr[4] = ptr[3];
        ptr[3] = ptr[2];
        ptr[2] = ptr[8];
        ptr[8] = tmp;

        ptr += 12;
      }
      gst_buffer_unmap (buf, &map);
      break;
    }
    default:
      goto invalid_width;
  }

  update_timestamps (dvdlpcmdec, buf, samples);

  if (dvdlpcmdec->lpcm_layout)
    gst_audio_buffer_reorder_channels (buf, dvdlpcmdec->info.finfo->format,
        dvdlpcmdec->info.channels, dvdlpcmdec->lpcm_layout,
        dvdlpcmdec->info.position);

  ret = gst_pad_push (dvdlpcmdec->srcpad, buf);

done:
  return ret;

  /* ERRORS */
drop:
  {
    GST_DEBUG_OBJECT (dvdlpcmdec,
        "Buffer of size %" G_GSIZE_FORMAT " is too small. Dropping", size);
    gst_buffer_unref (buf);
    ret = GST_FLOW_OK;
    goto done;
  }
not_negotiated:
  {
    GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, FORMAT, (NULL),
        ("Buffer pushed before negotiation"));
    gst_buffer_unref (buf);
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
invalid_width:
  {
    GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, WRONG_TYPE, (NULL),
        ("Invalid sample width configured"));
    gst_buffer_unref (buf);
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
}

static gboolean
dvdlpcmdec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstDvdLpcmDec *dvdlpcmdec;
  gboolean res;

  dvdlpcmdec = GST_DVDLPCMDEC (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_dvdlpcmdec_setcaps (pad, caps);
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment seg;

      gst_event_copy_segment (event, &seg);

      GST_DEBUG_OBJECT (dvdlpcmdec, "segment %" GST_SEGMENT_FORMAT, &seg);

      dvdlpcmdec->segment = seg;

      if (seg.format == GST_FORMAT_TIME) {
        dvdlpcmdec->timestamp = GST_CLOCK_TIME_NONE;
      } else {
        dvdlpcmdec->timestamp = 0;
      }
      res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&dvdlpcmdec->segment, GST_FORMAT_UNDEFINED);
      res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
      break;
    default:
      res = gst_pad_push_event (dvdlpcmdec->srcpad, event);
      break;
  }

  return res;
}

static GstStateChangeReturn
gst_dvdlpcmdec_change_state (GstElement * element, GstStateChange transition)
{
  GstDvdLpcmDec *dvdlpcmdec = GST_DVDLPCMDEC (element);
  GstStateChangeReturn res;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_dvdlpcm_reset (dvdlpcmdec);
      break;
    default:
      break;
  }

  res = parent_class->change_state (element, transition);

  switch (transition) {
    default:
      break;
  }

  return res;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (dvdlpcm_debug, "dvdlpcmdec", 0, "DVD LPCM Decoder");

  if (!gst_element_register (plugin, "dvdlpcmdec", GST_RANK_PRIMARY,
          GST_TYPE_DVDLPCMDEC)) {
    return FALSE;
  }

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    dvdlpcmdec,
    "Decode DVD LPCM frames into standard PCM",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
