/* GStreamer
 * Copyright (C) 2008 Pioneers of the Inevitable <songbird@songbirdnest.com>
 *
 * Authors: Michael Smith <msmith@songbirdnest.com>
 *
 * 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.
 */

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

#include <windows.h>
#include <mmreg.h>
#include <msacm.h>

#include <gst/gst.h>
#include <gst/riff/riff-media.h>

#define ACM_BUFFER_SIZE (64 * 1024)

#define GST_TYPE_ACM_MP3_DEC \
      (acmmp3dec_get_type())
#define GST_ACM_MP3_DEC(obj) \
      (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ACM_MP3_DEC,ACMMP3Dec))
#define GST_ACM_MP3_DEC_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ACM_MP3_DEC,ACMMP3DecClass))
#define GST_IS_ACM_MP3_DEC(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ACM_MP3_DEC))
#define GST_IS_ACM_MP3_DEC_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ACM_MP3_DEC))

#define GST_CAT_DEFAULT acmmp3dec_debug
GST_DEBUG_CATEGORY_STATIC (acmmp3dec_debug);

static GstStaticPadTemplate acmmp3dec_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "depth = (int)16, "
        "width = (int)16, "
        "endianness = (int)" G_STRINGIFY (G_BYTE_ORDER) ", "
        "signed = (boolean)TRUE, "
        "channels = (int) [1,2], " "rate = (int)[1, MAX]")
    );

static GstStaticPadTemplate acmmp3dec_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/mpeg, "
        "mpegversion = (int)1, "
        "layer = (int)3, "
        "rate = (int){ 8000, 11025, 12000, 16000, 22050, 24000, "
        "              32000, 44100, 48000 }, "
        "channels = (int)[1,2], " "parsed = (boolean) true")
    );

typedef struct _ACMMP3DecClass
{
  GstElementClass parent_class;
} ACMMP3DecClass;

typedef struct _ACMMP3Dec
{
  GstElement parent;

  GstPad *sinkpad;
  GstPad *srcpad;

  gboolean is_setup;

  MPEGLAYER3WAVEFORMAT infmt;
  WAVEFORMATEX outfmt;

  HACMSTREAM stream;
  ACMSTREAMHEADER header;

  /* Next timestamp to push */
  GstClockTime timestamp;

  /* From received caps */
  int rate;
  int channels;

  GstCaps *output_caps;
} ACMMP3Dec;

GType acmmp3dec_get_type (void);

#define acmmp3dec_parent_class parent_class
G_DEFINE_TYPE (ACMMP3Dec, acmmp3dec, GST_TYPE_ELEMENT);

static GstCaps *
acmmp3dec_caps_from_format (WAVEFORMATEX * fmt)
{
  return gst_riff_create_audio_caps (fmt->wFormatTag,
      NULL, (gst_riff_strf_auds *) fmt, NULL, NULL, NULL, NULL);
}

static gboolean
acmmp3dec_set_input_format (ACMMP3Dec * dec)
{
  dec->infmt.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
  dec->infmt.wfx.nChannels = dec->channels;
  dec->infmt.wfx.nSamplesPerSec = dec->rate;
  dec->infmt.wfx.nAvgBytesPerSec = 8000;        /* Has to be set, but actual
                                                   value doesn't matter */
  dec->infmt.wfx.nBlockAlign = 1;
  dec->infmt.wfx.wBitsPerSample = 0;
  dec->infmt.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
  dec->infmt.wID = MPEGLAYER3_ID_MPEG;
  dec->infmt.fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
  dec->infmt.nBlockSize = 1;    /* Needs to be non-zero, actual
                                   value doesn't matter */
  dec->infmt.nFramesPerBlock = 1;
  dec->infmt.nCodecDelay = 0;

  return TRUE;
}

static gboolean
acmmp3dec_set_output_format (ACMMP3Dec * dec)
{
  dec->outfmt.wFormatTag = WAVE_FORMAT_PCM;
  dec->outfmt.nChannels = dec->channels;
  dec->outfmt.nSamplesPerSec = dec->rate;
  dec->outfmt.nAvgBytesPerSec = 2 * dec->channels * dec->rate;
  dec->outfmt.nBlockAlign = 2 * dec->channels;
  dec->outfmt.wBitsPerSample = 16;
  dec->outfmt.cbSize = 0;

  return TRUE;
}

static gboolean
acmmp3dec_setup (ACMMP3Dec * dec)
{
  MMRESULT res;
  int destBufferSize;

  acmmp3dec_set_input_format (dec);
  acmmp3dec_set_output_format (dec);

  res =
      acmStreamOpen (&dec->stream, NULL, (LPWAVEFORMATEX) & dec->infmt,
      &dec->outfmt, 0, 0, 0, 0);
  if (res) {
    GST_WARNING_OBJECT (dec, "Failed to open ACM stream: %d", res);
    return FALSE;
  }

  dec->header.cbStruct = sizeof (ACMSTREAMHEADER);
  dec->header.fdwStatus = 0;
  dec->header.dwUser = 0;

  dec->header.pbSrc = (BYTE *) g_malloc (ACM_BUFFER_SIZE);
  dec->header.cbSrcLength = ACM_BUFFER_SIZE;
  dec->header.cbSrcLengthUsed = 0;
  dec->header.dwSrcUser = 0;

  /* Ask what buffer size we need to use for our output */
  acmStreamSize (dec->stream, ACM_BUFFER_SIZE,
      (LPDWORD) & destBufferSize, ACM_STREAMSIZEF_SOURCE);

  dec->header.pbDst = (BYTE *) g_malloc (destBufferSize);
  dec->header.cbDstLength = destBufferSize;
  dec->header.cbDstLengthUsed = 0;
  dec->header.dwDstUser = 0;

  res = acmStreamPrepareHeader (dec->stream, &dec->header, 0);
  if (res) {
    GST_WARNING_OBJECT (dec, "Failed to prepare ACM stream: %x", res);
    return FALSE;
  }

  dec->output_caps = acmmp3dec_caps_from_format (&dec->outfmt);
  if (dec->output_caps) {
    gst_pad_set_caps (dec->srcpad, dec->output_caps);
  }

  dec->timestamp = GST_CLOCK_TIME_NONE;
  dec->is_setup = TRUE;
  return TRUE;
}

static void
acmmp3dec_teardown (ACMMP3Dec * dec)
{
  if (dec->output_caps) {
    gst_caps_unref (dec->output_caps);
    dec->output_caps = NULL;
  }

  if (dec->header.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)
    acmStreamUnprepareHeader (dec->stream, &dec->header, 0);
  g_free (dec->header.pbSrc);
  g_free (dec->header.pbDst);
  memset (&dec->header, 0, sizeof (dec->header));

  if (dec->stream) {
    acmStreamClose (dec->stream, 0);
    dec->stream = 0;
  }

  dec->timestamp = GST_CLOCK_TIME_NONE;
  dec->is_setup = FALSE;
}

static gboolean
acmmp3dec_sink_setcaps (GstPad * pad, GstCaps * caps)
{
  ACMMP3Dec *dec = (ACMMP3Dec *) GST_PAD_PARENT (pad);
  GstStructure *structure;
  gboolean ret;

  structure = gst_caps_get_structure (caps, 0);
  gst_structure_get_int (structure, "channels", &dec->channels);
  gst_structure_get_int (structure, "rate", &dec->rate);

  if (dec->is_setup)
    acmmp3dec_teardown (dec);
  ret = acmmp3dec_setup (dec);

  return ret;
}

static GstFlowReturn
acmmp3dec_push_output (ACMMP3Dec * dec)
{
  GstFlowReturn ret = GST_FLOW_OK;

  if (dec->header.cbDstLengthUsed > 0) {
    GstBuffer *outbuf = gst_buffer_new_and_alloc (dec->header.cbDstLengthUsed);
    if (!outbuf) {
      GST_WARNING_OBJECT (dec, "cannot allocate a new GstBuffer");
      goto done_push_output;
    }

    if (gst_buffer_fill (outbuf, 0, dec->header.pbDst,
            dec->header.cbDstLengthUsed) != dec->header.cbDstLengthUsed) {
      gst_buffer_unref (outbuf);
      GST_WARNING_OBJECT (dec, "unable to fill output buffer");
      goto done_push_output;
    }

    if (dec->timestamp != GST_CLOCK_TIME_NONE)
      GST_BUFFER_TIMESTAMP (outbuf) = dec->timestamp;
    GST_BUFFER_DURATION (outbuf) =
        gst_util_uint64_scale_int (dec->header.cbDstLengthUsed, GST_SECOND,
        dec->rate * dec->channels * 2);

    GST_DEBUG_OBJECT (dec, "decoded buffer has ts %d, duration %d",
        (int) (GST_BUFFER_TIMESTAMP (outbuf)),
        (int) (GST_BUFFER_DURATION (outbuf)));

    if (dec->timestamp != GST_CLOCK_TIME_NONE)
      dec->timestamp += GST_BUFFER_DURATION (outbuf);

    GST_DEBUG_OBJECT (dec, "Pushing %lu byte decoded buffer",
        dec->header.cbDstLengthUsed);
    ret = gst_pad_push (dec->srcpad, outbuf);
  } else
    GST_DEBUG_OBJECT (dec, "Not pushing decoded buffer, no output");

done_push_output:
  return ret;
}

static GstFlowReturn
acmmp3dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  MMRESULT res;
  ACMMP3Dec *dec = (ACMMP3Dec *) GST_PAD_PARENT (pad);
  GstMapInfo map;
  GstFlowReturn ret = GST_FLOW_OK;

  gst_buffer_map (buf, &map, GST_MAP_READ);

  if (map.size > ACM_BUFFER_SIZE) {
    GST_WARNING_OBJECT (dec, "Impossibly large mp3 frame!");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE &&
      (dec->timestamp == GST_CLOCK_TIME_NONE ||
          GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
    dec->timestamp = GST_BUFFER_TIMESTAMP (buf);
  }

  memcpy (dec->header.pbSrc, map.data, map.size);
  dec->header.cbSrcLength = map.size;

  /* Now we have a buffer ready to go */
  res = acmStreamConvert (dec->stream, &dec->header,
      ACM_STREAMCONVERTF_BLOCKALIGN);
  if (res) {
    GST_WARNING_OBJECT (dec, "Failed to decode data");
    ret = GST_FLOW_OK;          /* Maybe it was just a corrupt frame */
    goto done;
  }

  if (dec->header.cbSrcLengthUsed > 0) {
    if (dec->header.cbSrcLengthUsed != dec->header.cbSrcLength) {
      GST_WARNING_OBJECT (dec, "ACM decoder didn't consume all data!");
      /* We could handle this, but it shouldn't be possible, so don't try
       * for now */
      ret = GST_FLOW_ERROR;
      goto done;
    }

    /* Write out any data produced */
    acmmp3dec_push_output (dec);
  }

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

  return ret;
}

static GstFlowReturn
acmmp3dec_finish_stream (ACMMP3Dec * dec)
{
  MMRESULT res;
  GstFlowReturn ret = GST_FLOW_OK;

  dec->header.cbSrcLength = 0;

  /* Flush out any remaining data internal to the decoder */
  res = acmStreamConvert (dec->stream, &dec->header,
      ACM_STREAMCONVERTF_BLOCKALIGN | ACM_STREAMCONVERTF_END);
  if (res) {
    GST_WARNING_OBJECT (dec, "Failed to decode data");
    return ret;
  }

  ret = acmmp3dec_push_output (dec);
  return ret;
}

static gboolean
acmmp3dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  ACMMP3Dec *dec = (ACMMP3Dec *) GST_PAD_PARENT (pad);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:{
      GstCaps *caps;
      gst_event_parse_caps (event, &caps);
      return acmmp3dec_sink_setcaps (pad, caps);
    }
    case GST_EVENT_EOS:
      acmmp3dec_finish_stream (dec);
      break;
    case GST_EVENT_FLUSH_STOP:
      if (dec->stream)
        acmStreamReset (dec->stream, 0);
      dec->timestamp = GST_CLOCK_TIME_NONE;
      break;
    default:
      break;
  }


  return gst_pad_push_event (dec->srcpad, event);
}

static void
acmmp3dec_dispose (GObject * obj)
{
  ACMMP3Dec *dec = (ACMMP3Dec *) obj;

  if (dec->is_setup)
    acmmp3dec_teardown (dec);

  G_OBJECT_CLASS (parent_class)->dispose (obj);
}

static void
acmmp3dec_init (ACMMP3Dec * dec)
{
  dec->sinkpad =
      gst_pad_new_from_static_template (&acmmp3dec_sink_template, "sink");
  gst_pad_set_chain_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (acmmp3dec_chain));
  gst_pad_set_event_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (acmmp3dec_sink_event));
  gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);

  dec->srcpad =
      gst_pad_new_from_static_template (&acmmp3dec_src_template, "src");
  gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);

}

static void
acmmp3dec_class_init (ACMMP3DecClass * klass)
{
  GObjectClass *gobjectclass = (GObjectClass *) klass;
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  gobjectclass->dispose = acmmp3dec_dispose;

  gst_element_class_add_static_pad_template (element_class,
      &acmmp3dec_sink_template);
  gst_element_class_add_static_pad_template (element_class,
      &acmmp3dec_src_template);
  gst_element_class_set_static_metadata (element_class, "ACM MP3 decoder",
      "Codec/Decoder/Audio", "Decode MP3 using ACM decoder",
      "Pioneers of the Inevitable <songbird@songbirdnest.com");
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (acmmp3dec_debug, "acmmp3dec", 0, "ACM Decoders");

  GST_INFO ("Registering ACM MP3 decoder");
  if (!gst_element_register (plugin, "acmmp3dec", GST_RANK_PRIMARY,
          GST_TYPE_ACM_MP3_DEC)) {
    return FALSE;
  }

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    acmmp3dec,
    "ACM MP3 Decoder",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
