/* 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-int, "
        "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);
}

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;
  }
  if (enc->header.pbSrc)
    g_free (enc->header.pbSrc);
  if (enc->header.pbDst)
    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);
    memcpy (GST_BUFFER_DATA (outbuf), enc->header.pbDst,
        enc->header.cbDstLengthUsed);
    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);
  }
  return ret;
}

static GstFlowReturn
acmenc_chain (GstPad * pad, GstBuffer * buf)
{
  MMRESULT res;
  ACMEnc *enc = (ACMEnc *) GST_PAD_PARENT (pad);
  guchar *data = GST_BUFFER_DATA (buf);
  gint len = GST_BUFFER_SIZE (buf);
  int chunklen;
  GstFlowReturn ret = GST_FLOW_OK;
  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);
  }
  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, GstEvent * event)
{
  ACMEnc *enc = (ACMEnc *) GST_PAD_PARENT (pad);
  gboolean res;
  switch (GST_EVENT_TYPE (event)) {
    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_setcaps_function (enc->sinkpad,
      GST_DEBUG_FUNCPTR (acmenc_sink_setcaps));
  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;
  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));
} static void

acmenc_base_init (ACMEncClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  ACMEncParams *params;
  ACMDRIVERDETAILS driverdetails;
  gchar *shortname, *longname, *detail, *description;
  MMRESULT res;

  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),
    (GBaseInitFunc) acmenc_base_init, 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/")
