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

/* This has to be bigger than some unspecified minimum size or things
 * break; I don't understand why (4kB isn't enough). Make it nice and
 * big.
 */
#define ACM_BUFFER_SIZE (64 * 1024)
enum
{
  ARG_0,
  ARG_BITRATE
};

#define DEFAULT_BITRATE 128000

#define ACMENC_PARAMS_QDATA g_quark_from_static_string("acmenc-params")

#define GST_CAT_DEFAULT acmenc_debug
GST_DEBUG_CATEGORY_STATIC (acmenc_debug);

static GstStaticPadTemplate acmenc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK, 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 acmenc_src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstElementClass *parent_class = NULL;
typedef struct _ACMEncClass
{
  GstElementClass parent_class;
  HACMDRIVERID driverId;
} ACMEncClass;

typedef struct _ACMEnc
{
  GstElement parent;
  GstPad *sinkpad;
  GstPad *srcpad;
  gboolean is_setup;
  WAVEFORMATEX infmt;
  WAVEFORMATEX *outfmt;
  HACMDRIVER driver;
  HACMSTREAM stream;
  ACMSTREAMHEADER header;

  /* Offset into input buffer to write next data */
  int offset;

  /* Number of bytes written */
  int bytes_output;

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

  /* Set in properties */
  int selected_bitrate;
  GstCaps *output_caps;
} ACMEnc;

typedef struct _ACMEncParams
{
  HACMDRIVERID driverId;
  HMODULE dll;
  gchar *name;
} ACMEncParams;

static GstCaps *
acmenc_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
acmenc_set_input_format (ACMEnc * enc, WAVEFORMATEX * infmt)
{
  infmt->wFormatTag = WAVE_FORMAT_PCM;
  infmt->nChannels = enc->channels;
  infmt->nSamplesPerSec = enc->rate;
  infmt->nAvgBytesPerSec = 2 * enc->channels * enc->rate;
  infmt->nBlockAlign = 2 * enc->channels;
  infmt->wBitsPerSample = 16;
  infmt->cbSize = 0;
  return TRUE;
}

static BOOL CALLBACK
acmenc_format_enum (HACMDRIVERID driverId, LPACMFORMATDETAILS fd,
    DWORD_PTR dwInstance, DWORD fdwSupport)
{
  ACMEnc *enc = (ACMEnc *) dwInstance;
  int oldbrdiff, newbrdiff;
  gboolean oldmatch, newmatch;
  if (!enc->outfmt) {

    /* First one is always the best so far */
    enc->outfmt =
        (WAVEFORMATEX *) g_malloc (fd->pwfx->cbSize + sizeof (WAVEFORMATEX));
    memcpy (enc->outfmt, fd->pwfx, fd->pwfx->cbSize + sizeof (WAVEFORMATEX));
    return TRUE;
  }

  /* We prefer a format with exact rate/channels match,
   * and the closest bitrate match. Otherwise, we accept
   * the closest bitrate match.
   */
  newmatch = (enc->channels == fd->pwfx->nChannels) &&
      (enc->rate == fd->pwfx->nSamplesPerSec);
  oldmatch = (enc->outfmt->nChannels == enc->channels) &&
      (enc->outfmt->nSamplesPerSec == enc->rate);
  newbrdiff = abs (enc->selected_bitrate - fd->pwfx->nAvgBytesPerSec * 8);
  oldbrdiff = abs (enc->selected_bitrate - enc->outfmt->nAvgBytesPerSec * 8);
  if ((newmatch && (!oldmatch || (newbrdiff < oldbrdiff))) ||
      (!newmatch && !oldmatch && (newbrdiff < oldbrdiff))) {
    g_free (enc->outfmt);
    enc->outfmt =
        (WAVEFORMATEX *) g_malloc (fd->pwfx->cbSize + sizeof (WAVEFORMATEX));
    memcpy (enc->outfmt, fd->pwfx, fd->pwfx->cbSize + sizeof (WAVEFORMATEX));
  }

  /* Always return TRUE to continue enumeration */
  return TRUE;
}

static gboolean
acmenc_set_format (ACMEnc * enc)
{
  WAVEFORMATEX *in = NULL;
  ACMFORMATDETAILS details;
  MMRESULT res;
  int maxSize;

  /* Input is fixed */
  acmenc_set_input_format (enc, &enc->infmt);

  /* Select the closest output that matches */
  res =
      acmMetrics ((HACMOBJ) enc->driver, ACM_METRIC_MAX_SIZE_FORMAT, &maxSize);

  /* Set the format to match what we'll be providing */
  in = (WAVEFORMATEX *) g_malloc (maxSize);
  acmenc_set_input_format (enc, in);
  in->cbSize = (WORD) (maxSize - sizeof (*in));
  details.cbStruct = sizeof (details);
  details.dwFormatIndex = 0;
  details.dwFormatTag = WAVE_FORMAT_UNKNOWN;
  details.fdwSupport = 0;
  details.pwfx = in;
  details.cbwfx = maxSize;

  /* We set enc->outfmt to the closest match in the callback */
  res =
      acmFormatEnum (enc->driver, &details, acmenc_format_enum, (DWORD_PTR) enc,
      ACM_FORMATENUMF_CONVERT);
  g_free (in);
  if (res) {
    GST_WARNING_OBJECT (enc, "Failed to enumerate formats");
    return FALSE;
  }
  if (!enc->outfmt) {
    GST_WARNING_OBJECT (enc, "No compatible output for input format");
    return FALSE;
  }
  return TRUE;
}

static gboolean
acmenc_setup (ACMEnc * enc)
{
  MMRESULT res;
  ACMEncClass *encclass = (ACMEncClass *) G_OBJECT_GET_CLASS (enc);
  int destBufferSize;
  res = acmDriverOpen (&enc->driver, encclass->driverId, 0);
  if (res) {
    GST_WARNING ("Failed to open ACM driver: %d", res);
    return FALSE;
  }
  if (!acmenc_set_format (enc))
    return FALSE;
  res =
      acmStreamOpen (&enc->stream, enc->driver, &enc->infmt, enc->outfmt, 0, 0,
      0, ACM_STREAMOPENF_NONREALTIME);
  if (res) {
    GST_WARNING_OBJECT (enc, "Failed to open ACM stream");
    return FALSE;
  }
  enc->header.cbStruct = sizeof (ACMSTREAMHEADER);
  enc->header.fdwStatus = 0;
  enc->header.dwUser = 0;
  enc->header.pbSrc = (BYTE *) g_malloc (ACM_BUFFER_SIZE);
  enc->header.cbSrcLength = ACM_BUFFER_SIZE;
  enc->header.cbSrcLengthUsed = 0;
  enc->header.dwSrcUser = 0;

  /* Ask what buffer size we need to use for our output */
  acmStreamSize (enc->stream, ACM_BUFFER_SIZE, (LPDWORD) & destBufferSize,
      ACM_STREAMSIZEF_SOURCE);
  enc->header.pbDst = (BYTE *) g_malloc (destBufferSize);
  enc->header.cbDstLength = destBufferSize;
  enc->header.cbDstLengthUsed = 0;
  enc->header.dwDstUser = 0;
  res = acmStreamPrepareHeader (enc->stream, &enc->header, 0);
  if (res) {
    GST_WARNING_OBJECT (enc, "Failed to prepare ACM stream");
    return FALSE;
  }
  enc->output_caps = acmenc_caps_from_format (enc->outfmt);
  if (enc->output_caps) {
    gst_pad_set_caps (enc->srcpad, enc->output_caps);
  }
  enc->is_setup = TRUE;
  return TRUE;
}

static void
acmenc_teardown (ACMEnc * enc)
{
  if (enc->outfmt) {
    g_free (enc->outfmt);
    enc->outfmt = NULL;
  }
  if (enc->output_caps) {
    gst_caps_unref (enc->output_caps);
    enc->output_caps = NULL;
  }
  g_free (enc->header.pbSrc);
  g_free (enc->header.pbDst);
  memset (&enc->header, 0, sizeof (enc->header));
  if (enc->stream) {
    acmStreamClose (enc->stream, 0);
    enc->stream = 0;
  }
  if (enc->driver) {
    acmDriverClose (enc->driver, 0);
    enc->driver = 0;
  }
  enc->bytes_output = 0;
  enc->offset = 0;
  enc->is_setup = FALSE;
}

static gboolean
acmenc_sink_setcaps (GstPad * pad, GstCaps * caps)
{
  ACMEnc *enc = (ACMEnc *) GST_PAD_PARENT (pad);
  GstStructure *structure;
  gboolean ret;
  structure = gst_caps_get_structure (caps, 0);
  gst_structure_get_int (structure, "channels", &enc->channels);
  gst_structure_get_int (structure, "rate", &enc->rate);
  if (enc->is_setup)
    acmenc_teardown (enc);
  ret = acmenc_setup (enc);
  return ret;
}

static GstFlowReturn
acmenc_push_output (ACMEnc * enc)
{
  GstFlowReturn ret = GST_FLOW_OK;
  if (enc->header.cbDstLengthUsed > 0) {
    GstBuffer *outbuf = gst_buffer_new_and_alloc (enc->header.cbDstLengthUsed);
    if (!outbuf) {
      GST_WARNING_OBJECT (enc, "cannot allocate a new GstBuffer");
      goto done_push_output;
    }

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

    if (enc->outfmt->nAvgBytesPerSec > 0) {

      /* We have a bitrate, so we can create a timestamp, hopefully */
      GST_BUFFER_TIMESTAMP (outbuf) =
          gst_util_uint64_scale_int (enc->bytes_output, GST_SECOND,
          enc->outfmt->nAvgBytesPerSec);
    }
    enc->bytes_output += enc->header.cbDstLengthUsed;
    GST_DEBUG_OBJECT (enc, "Pushing %lu byte encoded buffer",
        enc->header.cbDstLengthUsed);
    ret = gst_pad_push (enc->srcpad, outbuf);
  }

done_push_output:
  return ret;
}

static GstFlowReturn
acmenc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  MMRESULT res;
  ACMEnc *enc = (ACMEnc *) GST_PAD_PARENT (pad);
  GstMapInfo map;
  guchar *data;
  gint len;
  int chunklen;
  GstFlowReturn ret = GST_FLOW_OK;
  gst_buffer_map (buf, &map, GST_MAP_READ);
  len = map.size;
  data = map.data;
  while (len) {
    chunklen = MIN (len, ACM_BUFFER_SIZE - enc->offset);
    memcpy (enc->header.pbSrc + enc->offset, data, chunklen);
    enc->header.cbSrcLength = enc->offset + chunklen;
    data += chunklen;
    len -= chunklen;

    /* Now we have a buffer ready to go */
    res =
        acmStreamConvert (enc->stream, &enc->header,
        ACM_STREAMCONVERTF_BLOCKALIGN);
    if (res) {
      GST_WARNING_OBJECT (enc, "Failed to encode data");
      break;
    }
    if (enc->header.cbSrcLengthUsed > 0) {
      if (enc->header.cbSrcLengthUsed != enc->header.cbSrcLength) {

        /* Only part of input consumed */
        memmove (enc->header.pbSrc,
            enc->header.pbSrc + enc->header.cbSrcLengthUsed,
            enc->header.cbSrcLengthUsed);
        enc->offset -= enc->header.cbSrcLengthUsed;
      }

      else
        enc->offset = 0;
    }

    /* Write out any data produced */
    acmenc_push_output (enc);
  }
  gst_buffer_unmap (buf, &map);
  return ret;
}

static GstFlowReturn
acmenc_finish_stream (ACMEnc * enc)
{
  MMRESULT res;
  GstFlowReturn ret = GST_FLOW_OK;
  int len;

  /* Ensure any remaining input data is consumed */
  len = enc->offset;
  enc->header.cbSrcLength = len;
  res =
      acmStreamConvert (enc->stream, &enc->header,
      ACM_STREAMCONVERTF_BLOCKALIGN | ACM_STREAMCONVERTF_END);
  if (res) {
    GST_WARNING_OBJECT (enc, "Failed to encode data");
    return ret;
  }
  ret = acmenc_push_output (enc);
  return ret;
}

static gboolean
acmenc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  ACMEnc *enc = (ACMEnc *) GST_PAD_PARENT (pad);
  gboolean res;
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:{
      GstCaps *caps;
      gst_event_parse_caps (event, &caps);
      return acmenc_sink_setcaps (pad, caps);
    }
    case GST_EVENT_EOS:
      acmenc_finish_stream (enc);
      res = gst_pad_push_event (enc->srcpad, event);
      break;
    default:
      res = gst_pad_push_event (enc->srcpad, event);
      break;
  }
  return res;
}

static void
acmenc_dispose (GObject * obj)
{
  ACMEnc *enc = (ACMEnc *) obj;
  acmenc_teardown (enc);
  G_OBJECT_CLASS (parent_class)->dispose (obj);
} static void

acmenc_init (ACMEnc * enc)
{
  enc->sinkpad =
      gst_pad_new_from_static_template (&acmenc_sink_template, "sink");
  gst_pad_set_chain_function (enc->sinkpad, GST_DEBUG_FUNCPTR (acmenc_chain));
  gst_pad_set_event_function (enc->sinkpad,
      GST_DEBUG_FUNCPTR (acmenc_sink_event));
  gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
  enc->srcpad = gst_pad_new_from_static_template (&acmenc_src_template, "src");
  gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
  enc->selected_bitrate = DEFAULT_BITRATE;
} static void

acmenc_set_property (GObject * obj, guint prop_id, const GValue * value,
    GParamSpec * pspec)
{
  ACMEnc *enc = (ACMEnc *) obj;
  switch (prop_id) {
    case ARG_BITRATE:
      enc->selected_bitrate = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
  }
}

static void
acmenc_get_property (GObject * obj, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  ACMEnc *enc = (ACMEnc *) obj;
  switch (prop_id) {
    case ARG_BITRATE:
      g_value_set_int (value, enc->selected_bitrate);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
  }
}

static void
acmenc_class_init (ACMEncClass * klass)
{
  GObjectClass *gobjectclass = (GObjectClass *) klass;
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  ACMEncParams *params;
  ACMDRIVERDETAILS driverdetails;
  gchar *shortname, *longname, *detail, *description;
  MMRESULT res;

  parent_class = (GstElementClass *) g_type_class_peek_parent (klass);
  gobjectclass->dispose = acmenc_dispose;
  gobjectclass->set_property = acmenc_set_property;
  gobjectclass->get_property = acmenc_get_property;
  g_object_class_install_property (gobjectclass, ARG_BITRATE,
      g_param_spec_int ("bitrate", "Bitrate", "Bitrate to encode at (in bps)",
          0, 1000000, DEFAULT_BITRATE, G_PARAM_READWRITE));

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&acmenc_sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&acmenc_src_template));
  params =
      (ACMEncParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
      ACMENC_PARAMS_QDATA);
  g_assert (params);
  memset (&driverdetails, 0, sizeof (driverdetails));
  driverdetails.cbStruct = sizeof (driverdetails);
  res = acmDriverDetails (params->driverId, &driverdetails, 0);
  if (res) {
    GST_WARNING ("Could not get driver details: %d", res);
  }
  shortname =
      g_utf16_to_utf8 ((gunichar2 *) driverdetails.szShortName, -1, NULL, NULL,
      NULL);
  longname =
      g_utf16_to_utf8 ((gunichar2 *) driverdetails.szLongName, -1, NULL, NULL,
      NULL);
  detail = g_strdup_printf ("ACM Encoder: %s", (shortname
          && *shortname) ? shortname : params->name);
  description = g_strdup_printf ("ACM Encoder: %s", (longname
          && *longname) ? longname : params->name);
  gst_element_class_set_static_metadata (element_class, detail,
      "Codec/Encoder/Audio", description,
      "Pioneers of the Inevitable <songbird@songbirdnest.com>");
  g_free (shortname);
  g_free (longname);
  g_free (description);
  g_free (detail);
  klass->driverId = params->driverId;
}

static ACMEncParams *
acmenc_open_driver (wchar_t * filename)
{
  HACMDRIVERID driverid = NULL;
  HMODULE mod = NULL;
  FARPROC func;
  MMRESULT res;
  ACMEncParams *params;
  mod = LoadLibraryW (filename);
  if (!mod) {
    GST_WARNING ("Failed to load ACM");
    goto done;
  }
  func = GetProcAddress (mod, "DriverProc");
  if (!func) {
    GST_WARNING ("Failed to find 'DriverProc' in ACM");
    goto done;
  }
  res =
      acmDriverAdd (&driverid, mod, (LPARAM) func, 0, ACM_DRIVERADDF_FUNCTION);
  if (res) {
    GST_WARNING ("Failed to add ACM driver: %d", res);
    goto done;
  }
  params = g_new0 (ACMEncParams, 1);
  params->dll = mod;
  params->driverId = driverid;
  return params;
done:if (driverid)
    acmDriverRemove (driverid, 0);
  if (mod)
    FreeLibrary (mod);
  return NULL;
}

static gboolean
acmenc_register_file (GstPlugin * plugin, wchar_t * filename)
{
  ACMEncParams *params;
  gchar *type_name, *name;
  GType type;
  GTypeInfo typeinfo = {
    sizeof (ACMEncClass),
    NULL, NULL,
    (GClassInitFunc) acmenc_class_init, NULL, NULL, sizeof (ACMEnc),
    0, (GInstanceInitFunc) acmenc_init,
  };
  params = acmenc_open_driver (filename);
  if (!params)
    return FALSE;

  /* Strip .acm off the end, convert to utf-8 */
  name =
      g_utf16_to_utf8 (filename, (glong) wcslen (filename) - 4, NULL, NULL,
      NULL);
  params->name = name;
  type_name = g_strdup_printf ("acmenc_%s", name);
  type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);

  /* Store params in type qdata */
  g_type_set_qdata (type, ACMENC_PARAMS_QDATA, (gpointer) params);

  /* register type */
  if (!gst_element_register (plugin, type_name, GST_RANK_NONE, type)) {
    g_warning ("Failed to register %s", type_name);
    g_type_set_qdata (type, ACMENC_PARAMS_QDATA, NULL);
    g_free (name);
    g_free (type_name);
    g_free (params);
    return FALSE;
  }
  g_free (type_name);
  return TRUE;
}

static gboolean
acmenc_register (GstPlugin * plugin)
{
  int res;
  wchar_t dirname[1024];
  WIN32_FIND_DATAW filedata;
  HANDLE find;
  res = GetSystemDirectoryW (dirname, sizeof (dirname) / sizeof (wchar_t));
  if (!res || res > 1000) {
    GST_WARNING ("Couldn't get system directory");
    return FALSE;
  }
  wcscat (dirname, L"\\*.acm");
  find = FindFirstFileW (dirname, &filedata);
  if (find == INVALID_HANDLE_VALUE) {
    GST_WARNING ("Failed to find ACM files: %lx", GetLastError ());
    return FALSE;
  }

  do {
    char *filename =
        g_utf16_to_utf8 ((gunichar2 *) filedata.cFileName, -1, NULL, NULL,
        NULL);
    GST_INFO ("Registering ACM filter from file %s", filename);
    if (acmenc_register_file (plugin, filedata.cFileName))
      GST_INFO ("Loading filter from ACM '%s' succeeded", filename);

    else
      GST_WARNING ("Loading filter from ACM '%s' failed", filename);
    g_free (filename);
  } while (FindNextFileW (find, &filedata));
  FindClose (find);
  return TRUE;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  gboolean res;
  GST_DEBUG_CATEGORY_INIT (acmenc_debug, "acmenc", 0, "ACM Encoders");
  GST_INFO ("Registering ACM encoders");
  res = acmenc_register (plugin);
  return res;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, acmenc,
    "ACM Encoder wrapper", plugin_init, VERSION, "LGPL", "GStreamer",
    "http://gstreamer.net/")
