/* 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_static_pad_template (element_class,
      &acmenc_sink_template);
  gst_element_class_add_static_pad_template (element_class,
      &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", GST_PACKAGE_NAME,
    GST_PACKAGE_ORIGIN)
