/* 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-private2-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 ]")
    );

#define gst_dvdlpcmdec_parent_class parent_class
G_DEFINE_TYPE (GstDvdLpcmDec, gst_dvdlpcmdec, GST_TYPE_AUDIO_DECODER);

static gboolean gst_dvdlpcmdec_set_format (GstAudioDecoder * bdec,
    GstCaps * caps);
static GstFlowReturn gst_dvdlpcmdec_parse (GstAudioDecoder * bdec,
    GstAdapter * adapter, gint * offset, gint * len);
static GstFlowReturn gst_dvdlpcmdec_handle_frame (GstAudioDecoder * bdec,
    GstBuffer * buffer);
static GstFlowReturn gst_dvdlpcmdec_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);


static void
gst_dvdlpcmdec_class_init (GstDvdLpcmDecClass * klass)
{
  GstElementClass *element_class;
  GstAudioDecoderClass *gstbase_class;

  element_class = (GstElementClass *) klass;
  gstbase_class = (GstAudioDecoderClass *) klass;

  gstbase_class->set_format = GST_DEBUG_FUNCPTR (gst_dvdlpcmdec_set_format);
  gstbase_class->parse = GST_DEBUG_FUNCPTR (gst_dvdlpcmdec_parse);
  gstbase_class->handle_frame = GST_DEBUG_FUNCPTR (gst_dvdlpcmdec_handle_frame);

  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>");

  GST_DEBUG_CATEGORY_INIT (dvdlpcm_debug, "dvdlpcmdec", 0, "DVD LPCM Decoder");
}

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

  dvdlpcmdec->header = 0;

  dvdlpcmdec->mode = GST_LPCM_UNKNOWN;
}

static void
gst_dvdlpcmdec_init (GstDvdLpcmDec * dvdlpcmdec)
{
  gst_dvdlpcm_reset (dvdlpcmdec);

  gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
      (dvdlpcmdec), TRUE);
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (dvdlpcmdec));

  /* retrieve and intercept base class chain.
   * Quite HACKish, but that's dvd specs/caps for you,
   * since one buffer needs to be split into 2 frames */
  dvdlpcmdec->base_chain =
      GST_PAD_CHAINFUNC (GST_AUDIO_DECODER_SINK_PAD (dvdlpcmdec));
  gst_pad_set_chain_function (GST_AUDIO_DECODER_SINK_PAD (dvdlpcmdec),
      GST_DEBUG_FUNCPTR (gst_dvdlpcmdec_chain));
}

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_audio_decoder_merge_tags (GST_AUDIO_DECODER (dvdlpcmdec), taglist,
      GST_TAG_MERGE_REPLACE);
  gst_tag_list_unref (taglist);
}

static gboolean
gst_dvdlpcmdec_set_output_format (GstDvdLpcmDec * dvdlpcmdec)
{
  gboolean res = TRUE;

  res = gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (dvdlpcmdec),
      &dvdlpcmdec->info);
  if (res) {
    GST_DEBUG_OBJECT (dvdlpcmdec, "Successfully set output format");

    gst_dvdlpcmdec_send_tags (dvdlpcmdec);
  } else {
    GST_DEBUG_OBJECT (dvdlpcmdec, "Failed to set output format");
  }

  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];
    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);
    if (memcmp (position, sorted_position,
            channels * sizeof (position[0])) != 0)
      dec->lpcm_layout = position;
    else
      dec->lpcm_layout = NULL;
  } else {
    gst_audio_info_set_format (&dec->info, format, rate, channels, NULL);
  }
}

static gboolean
gst_dvdlpcmdec_set_format (GstAudioDecoder * bdec, GstCaps * caps)
{
  GstDvdLpcmDec *dvdlpcmdec = GST_DVDLPCMDEC (bdec);
  GstStructure *structure;
  gboolean res = TRUE;
  GstAudioFormat format;
  gint rate, channels, width;

  gst_dvdlpcm_reset (dvdlpcmdec);

  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")) {
    dvdlpcmdec->mode = GST_LPCM_DVD;
    goto done;
  }
  if (gst_structure_has_name (structure, "audio/x-private2-lpcm")) {
    dvdlpcmdec->mode = GST_LPCM_1394;
    goto done;
  }

  dvdlpcmdec->mode = GST_LPCM_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_output_format (dvdlpcmdec);

done:
  return res;

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

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 (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstDvdLpcmDec *dvdlpcmdec = GST_DVDLPCMDEC (parent);
  guint8 data[2];
  gsize size;
  guint first_access;
  GstBuffer *subbuf;
  GstFlowReturn ret = GST_FLOW_OK;
  gint off, len;

  if (dvdlpcmdec->mode != GST_LPCM_DVD)
    return dvdlpcmdec->base_chain (pad, parent, buf);

  size = gst_buffer_get_size (buf);
  if (size < 5)
    goto too_small;

  gst_buffer_extract (buf, 0, data, 2);
  first_access = (data[0] << 8) | data[1];
  if (first_access > size)
    goto invalid_data;

  /* After first_access, we have an additional 3 bytes of header data; 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 */
  off = 2;

  if (first_access > 4) {
    /* length of first buffer */
    len = first_access - 1;

    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);
    GST_BUFFER_TIMESTAMP (subbuf) = GST_CLOCK_TIME_NONE;
    ret = dvdlpcmdec->base_chain (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) {
      GstMemory *header, *tmp;
      subbuf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, off, len);
      tmp = gst_buffer_peek_memory (buf, 0);
      header = gst_memory_copy (tmp, 2, 3);
      gst_buffer_prepend_memory (subbuf, header);
      GST_BUFFER_TIMESTAMP (subbuf) = GST_BUFFER_TIMESTAMP (buf);

      ret = dvdlpcmdec->base_chain (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 = dvdlpcmdec->base_chain (pad, parent, subbuf);
  }

done:
  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;
  }
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_parse_dvd (GstDvdLpcmDec * dvdlpcmdec, GstAdapter * adapter,
    gint * offset, gint * len)
{
  guint32 header;
  const guint8 *data;

  data = (const guint8 *) gst_adapter_map (adapter, 3);
  if (!data)
    goto too_small;

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

  gst_adapter_unmap (adapter);

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

    if (!gst_dvdlpcmdec_set_output_format (dvdlpcmdec))
      goto negotiation_failed;

    dvdlpcmdec->header = header;
  }

  *offset = 3;
  *len = gst_adapter_available (adapter) - 3;

  return GST_FLOW_OK;

  /* 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"));
    *offset = gst_adapter_available (adapter);
    return GST_FLOW_EOS;
  }
negotiation_failed:
  {
    GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, FORMAT, (NULL),
        ("Failed to configure output format"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
}

static GstFlowReturn
gst_dvdlpcmdec_parse_1394 (GstDvdLpcmDec * dvdlpcmdec, GstAdapter * adapter,
    gint * offset, gint * len)
{
  guint32 header;
  const guint8 *data;

  data = (const guint8 *) gst_adapter_map (adapter, 4);
  if (!data)
    goto too_small;

  header = GST_READ_UINT32_BE (data);

  gst_adapter_unmap (adapter);

  /* see if we have a new header */
  if (header != dvdlpcmdec->header) {
    GstAudioFormat format;
    gint rate, channels;

    if (header >> 24 != 0xa0)
      goto invalid_data;

    switch ((header >> 6) & 0x3) {
      case 0x0:
        format = GST_AUDIO_FORMAT_S16BE;
        dvdlpcmdec->width = 16;
        break;
      default:
        format = GST_AUDIO_FORMAT_UNKNOWN;
        dvdlpcmdec->width = 0;
        GST_WARNING ("Invalid quantization word length!");
        break;
    }

    switch ((header >> 3) & 0x7) {
      case 0x1:
        rate = 44100;
        break;
      case 0x2:
        rate = 48000;
        break;
      default:
        rate = 0;
        GST_WARNING ("Invalid audio sampling frequency!");
        break;
    }
    switch (header & 0x7) {
      case 0x0:                /* 2 channels dual-mono */
      case 0x1:                /* 2 channles stereo */
        channels = 2;
        break;
      default:
        channels = 0;
        GST_WARNING ("Invalid number of audio channels!");
        break;
    }

    gst_dvdlpcmdec_update_audio_formats (dvdlpcmdec, channels, rate, format);

    if (!gst_dvdlpcmdec_set_output_format (dvdlpcmdec))
      goto negotiation_failed;

    dvdlpcmdec->header = header;
  }

  *offset = 4;
  *len = gst_adapter_available (adapter) - 4;

  return GST_FLOW_OK;

  /* 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"));
    *offset = gst_adapter_available (adapter);
    return GST_FLOW_EOS;
  }
invalid_data:
  {
    GST_ELEMENT_WARNING (dvdlpcmdec, STREAM, DECODE,
        ("Invalid data found parsing LPCM packet"),
        ("LPCM packet contains invalid sub_stream_id."));
    return GST_FLOW_ERROR;
  }
negotiation_failed:
  {
    GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, FORMAT, (NULL),
        ("Failed to configure output format"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
}

static GstFlowReturn
gst_dvdlpcmdec_parse (GstAudioDecoder * bdec, GstAdapter * adapter,
    gint * offset, gint * len)
{
  GstDvdLpcmDec *dvdlpcmdec = GST_DVDLPCMDEC (bdec);

  switch (dvdlpcmdec->mode) {
    case GST_LPCM_UNKNOWN:
      return GST_FLOW_NOT_NEGOTIATED;

    case GST_LPCM_RAW:
      *offset = 0;
      *len = gst_adapter_available (adapter);
      return GST_FLOW_OK;

    case GST_LPCM_DVD:
      return gst_dvdlpcmdec_parse_dvd (dvdlpcmdec, adapter, offset, len);

    case GST_LPCM_1394:
      return gst_dvdlpcmdec_parse_1394 (dvdlpcmdec, adapter, offset, len);
  }
  return GST_FLOW_ERROR;
}

static GstFlowReturn
gst_dvdlpcmdec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
{
  GstDvdLpcmDec *dvdlpcmdec = GST_DVDLPCMDEC (bdec);
  gsize size;
  GstFlowReturn ret;
  guint samples = 0;
  gint rate, channels;

  /* no fancy draining */
  if (G_UNLIKELY (!buf))
    return GST_FLOW_OK;

  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;

  /* 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;

      gst_buffer_ref (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);
      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 srcmap, destmap;
      guint8 *src, *dest;
      GstBuffer *outbuf;

      samples = size / channels / 3;

      if (samples < 1)
        goto drop;

      outbuf = gst_buffer_new_allocate (NULL, size, NULL);
      gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);

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

      for (i = 0; i < count; i++) {
        dest[0] = src[0];
        dest[1] = src[1];
        dest[11] = src[11];
        dest[10] = src[7];
        dest[7] = src[5];
        dest[5] = src[9];
        dest[9] = src[6];
        dest[6] = src[4];
        dest[4] = src[3];
        dest[3] = src[2];
        dest[2] = src[8];
        dest[8] = src[10];

        src += 12;
        dest += 12;
      }
      gst_buffer_unmap (outbuf, &destmap);
      gst_buffer_unmap (buf, &srcmap);
      buf = outbuf;
      break;
    }
    default:
      goto invalid_width;
  }

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

  ret = gst_audio_decoder_finish_frame (bdec, buf, 1);

done:
  return ret;

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

static gboolean
plugin_init (GstPlugin * plugin)
{

  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);
