/*
 * Copyright (C) 2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
 * Copyright (C) 2018 Centricular Ltd.
 *   Author: Nirbheek Chauhan <nirbheek@centricular.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 "gstwasapiutil.h"
#include "gstwasapidevice.h"

GST_DEBUG_CATEGORY_EXTERN (gst_wasapi_debug);
#define GST_CAT_DEFAULT gst_wasapi_debug

/* This was only added to MinGW in ~2015 and our Cerbero toolchain is too old */
#if defined(_MSC_VER)
#include <functiondiscoverykeys_devpkey.h>
#elif !defined(PKEY_Device_FriendlyName)
#include <propkey.h>
DEFINE_PROPERTYKEY (PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,
    0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
DEFINE_PROPERTYKEY (PKEY_AudioEngine_DeviceFormat, 0xf19f064d, 0x82c, 0x4e27,
    0xbc, 0x73, 0x68, 0x82, 0xa1, 0xbb, 0x8e, 0x4c, 0);
#endif

/* __uuidof is only available in C++, so we hard-code the GUID values for all
 * these. This is ok because these are ABI. */
const CLSID CLSID_MMDeviceEnumerator = { 0xbcde0395, 0xe52f, 0x467c,
  {0x8e, 0x3d, 0xc4, 0x57, 0x92, 0x91, 0x69, 0x2e}
};

const IID IID_IMMDeviceEnumerator = { 0xa95664d2, 0x9614, 0x4f35,
  {0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6}
};

const IID IID_IMMEndpoint = { 0x1be09788, 0x6894, 0x4089,
  {0x85, 0x86, 0x9a, 0x2a, 0x6c, 0x26, 0x5a, 0xc5}
};

const IID IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32,
  {0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2}
};

const IID IID_IAudioClient3 = { 0x7ed4ee07, 0x8e67, 0x4cd4,
  {0x8c, 0x1a, 0x2b, 0x7a, 0x59, 0x87, 0xad, 0x42}
};

const IID IID_IAudioClock = { 0xcd63314f, 0x3fba, 0x4a1b,
  {0x81, 0x2c, 0xef, 0x96, 0x35, 0x87, 0x28, 0xe7}
};

const IID IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0,
  {0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17}
};

const IID IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483,
  {0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2}
};

static struct
{
  guint64 wasapi_pos;
  GstAudioChannelPosition gst_pos;
} wasapi_to_gst_pos[] = {
  {SPEAKER_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT},
  {SPEAKER_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
  {SPEAKER_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
  {SPEAKER_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1},
  {SPEAKER_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT},
  {SPEAKER_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
  {SPEAKER_FRONT_LEFT_OF_CENTER,
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER},
  {SPEAKER_FRONT_RIGHT_OF_CENTER,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER},
  {SPEAKER_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
  /* Enum values diverge from this point onwards */
  {SPEAKER_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT},
  {SPEAKER_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT},
  {SPEAKER_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER},
  {SPEAKER_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT},
  {SPEAKER_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER},
  {SPEAKER_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT},
  {SPEAKER_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT},
  {SPEAKER_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER},
  {SPEAKER_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT}
};

static int windows_major_version = 0;

static struct
{
  HMODULE dll;
  gboolean tried_loading;

    HANDLE (WINAPI * AvSetMmThreadCharacteristics) (LPCSTR, LPDWORD);
    BOOL (WINAPI * AvRevertMmThreadCharacteristics) (HANDLE);
} gst_wasapi_avrt_tbl = {
0};

gboolean
gst_wasapi_util_have_audioclient3 (void)
{
  if (windows_major_version > 0)
    return windows_major_version == 10;

  if (g_getenv ("GST_WASAPI_DISABLE_AUDIOCLIENT3") != NULL) {
    windows_major_version = 6;
    return FALSE;
  }

  /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms724834(v=vs.85).aspx */
  windows_major_version = 6;
  if (g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_ANY))
    windows_major_version = 10;

  return windows_major_version == 10;
}

GType
gst_wasapi_device_role_get_type (void)
{
  static const GEnumValue values[] = {
    {GST_WASAPI_DEVICE_ROLE_CONSOLE,
        "Games, system notifications, voice commands", "console"},
    {GST_WASAPI_DEVICE_ROLE_MULTIMEDIA, "Music, movies, recorded media",
        "multimedia"},
    {GST_WASAPI_DEVICE_ROLE_COMMS, "Voice communications", "comms"},
    {0, NULL, NULL}
  };
  static volatile GType id = 0;

  if (g_once_init_enter ((gsize *) & id)) {
    GType _id;

    _id = g_enum_register_static ("GstWasapiDeviceRole", values);

    g_once_init_leave ((gsize *) & id, _id);
  }

  return id;
}

gint
gst_wasapi_device_role_to_erole (gint role)
{
  switch (role) {
    case GST_WASAPI_DEVICE_ROLE_CONSOLE:
      return eConsole;
    case GST_WASAPI_DEVICE_ROLE_MULTIMEDIA:
      return eMultimedia;
    case GST_WASAPI_DEVICE_ROLE_COMMS:
      return eCommunications;
    default:
      g_assert_not_reached ();
  }
}

gint
gst_wasapi_erole_to_device_role (gint erole)
{
  switch (erole) {
    case eConsole:
      return GST_WASAPI_DEVICE_ROLE_CONSOLE;
    case eMultimedia:
      return GST_WASAPI_DEVICE_ROLE_MULTIMEDIA;
    case eCommunications:
      return GST_WASAPI_DEVICE_ROLE_COMMS;
    default:
      g_assert_not_reached ();
  }
}

static const gchar *
hresult_to_string_fallback (HRESULT hr)
{
  const gchar *s = "unknown error";

  switch (hr) {
    case AUDCLNT_E_NOT_INITIALIZED:
      s = "AUDCLNT_E_NOT_INITIALIZED";
      break;
    case AUDCLNT_E_ALREADY_INITIALIZED:
      s = "AUDCLNT_E_ALREADY_INITIALIZED";
      break;
    case AUDCLNT_E_WRONG_ENDPOINT_TYPE:
      s = "AUDCLNT_E_WRONG_ENDPOINT_TYPE";
      break;
    case AUDCLNT_E_DEVICE_INVALIDATED:
      s = "AUDCLNT_E_DEVICE_INVALIDATED";
      break;
    case AUDCLNT_E_NOT_STOPPED:
      s = "AUDCLNT_E_NOT_STOPPED";
      break;
    case AUDCLNT_E_BUFFER_TOO_LARGE:
      s = "AUDCLNT_E_BUFFER_TOO_LARGE";
      break;
    case AUDCLNT_E_OUT_OF_ORDER:
      s = "AUDCLNT_E_OUT_OF_ORDER";
      break;
    case AUDCLNT_E_UNSUPPORTED_FORMAT:
      s = "AUDCLNT_E_UNSUPPORTED_FORMAT";
      break;
    case AUDCLNT_E_INVALID_DEVICE_PERIOD:
      s = "AUDCLNT_E_INVALID_DEVICE_PERIOD";
      break;
    case AUDCLNT_E_INVALID_SIZE:
      s = "AUDCLNT_E_INVALID_SIZE";
      break;
    case AUDCLNT_E_DEVICE_IN_USE:
      s = "AUDCLNT_E_DEVICE_IN_USE";
      break;
    case AUDCLNT_E_BUFFER_OPERATION_PENDING:
      s = "AUDCLNT_E_BUFFER_OPERATION_PENDING";
      break;
    case AUDCLNT_E_BUFFER_SIZE_ERROR:
      s = "AUDCLNT_E_BUFFER_SIZE_ERROR";
      break;
    case AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED:
      s = "AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED";
      break;
    case AUDCLNT_E_THREAD_NOT_REGISTERED:
      s = "AUDCLNT_E_THREAD_NOT_REGISTERED";
      break;
    case AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED:
      s = "AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED";
      break;
    case AUDCLNT_E_ENDPOINT_CREATE_FAILED:
      s = "AUDCLNT_E_ENDPOINT_CREATE_FAILED";
      break;
    case AUDCLNT_E_SERVICE_NOT_RUNNING:
      s = "AUDCLNT_E_SERVICE_NOT_RUNNING";
      break;
    case AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED:
      s = "AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED";
      break;
    case AUDCLNT_E_EXCLUSIVE_MODE_ONLY:
      s = "AUDCLNT_E_EXCLUSIVE_MODE_ONLY";
      break;
    case AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL:
      s = "AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL";
      break;
    case AUDCLNT_E_EVENTHANDLE_NOT_SET:
      s = "AUDCLNT_E_EVENTHANDLE_NOT_SET";
      break;
    case AUDCLNT_E_INCORRECT_BUFFER_SIZE:
      s = "AUDCLNT_E_INCORRECT_BUFFER_SIZE";
      break;
    case AUDCLNT_E_CPUUSAGE_EXCEEDED:
      s = "AUDCLNT_E_CPUUSAGE_EXCEEDED";
      break;
    case AUDCLNT_S_BUFFER_EMPTY:
      s = "AUDCLNT_S_BUFFER_EMPTY";
      break;
    case AUDCLNT_S_THREAD_ALREADY_REGISTERED:
      s = "AUDCLNT_S_THREAD_ALREADY_REGISTERED";
      break;
    case AUDCLNT_S_POSITION_STALLED:
      s = "AUDCLNT_S_POSITION_STALLED";
      break;
    case E_POINTER:
      s = "E_POINTER";
      break;
    case E_INVALIDARG:
      s = "E_INVALIDARG";
      break;
  }

  return s;
}

gchar *
gst_wasapi_util_hresult_to_string (HRESULT hr)
{
  DWORD flags;
  gchar *ret_text;
  LPTSTR error_text = NULL;

  flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
      | FORMAT_MESSAGE_IGNORE_INSERTS;
  FormatMessage (flags, NULL, hr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR) & error_text, 0, NULL);

  /* If we couldn't get the error msg, try the fallback switch statement */
  if (error_text == NULL)
    return g_strdup (hresult_to_string_fallback (hr));

#ifdef UNICODE
  /* If UNICODE is defined, LPTSTR is LPWSTR which is UTF-16 */
  ret_text = g_utf16_to_utf8 (error_text, 0, NULL, NULL, NULL);
#else
  ret_text = g_strdup (error_text);
#endif

  LocalFree (error_text);
  return ret_text;
}

static IMMDeviceEnumerator *
gst_wasapi_util_get_device_enumerator (GstElement * self)
{
  HRESULT hr;
  IMMDeviceEnumerator *enumerator = NULL;

  hr = CoCreateInstance (&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
      &IID_IMMDeviceEnumerator, (void **) &enumerator);
  HR_FAILED_RET (hr, CoCreateInstance (MMDeviceEnumerator), NULL);

  return enumerator;
}

gboolean
gst_wasapi_util_get_devices (GstElement * self, gboolean active,
    GList ** devices)
{
  gboolean res = FALSE;
  static GstStaticCaps scaps = GST_STATIC_CAPS (GST_WASAPI_STATIC_CAPS);
  DWORD dwStateMask = active ? DEVICE_STATE_ACTIVE : DEVICE_STATEMASK_ALL;
  IMMDeviceCollection *device_collection = NULL;
  IMMDeviceEnumerator *enumerator = NULL;
  const gchar *device_class, *element_name;
  guint ii, count;
  HRESULT hr;

  *devices = NULL;

  enumerator = gst_wasapi_util_get_device_enumerator (self);
  if (!enumerator)
    return FALSE;

  hr = IMMDeviceEnumerator_EnumAudioEndpoints (enumerator, eAll, dwStateMask,
      &device_collection);
  HR_FAILED_GOTO (hr, IMMDeviceEnumerator::EnumAudioEndpoints, err);

  hr = IMMDeviceCollection_GetCount (device_collection, &count);
  HR_FAILED_GOTO (hr, IMMDeviceCollection::GetCount, err);

  /* Create a GList of GstDevices* to return */
  for (ii = 0; ii < count; ii++) {
    IMMDevice *item = NULL;
    IMMEndpoint *endpoint = NULL;
    IAudioClient *client = NULL;
    IPropertyStore *prop_store = NULL;
    WAVEFORMATEX *format = NULL;
    gchar *description = NULL;
    gchar *strid = NULL;
    EDataFlow dataflow;
    PROPVARIANT var;
    wchar_t *wstrid;
    GstDevice *device;
    GstStructure *props;
    GstCaps *caps;

    hr = IMMDeviceCollection_Item (device_collection, ii, &item);
    if (hr != S_OK)
      continue;

    hr = IMMDevice_QueryInterface (item, &IID_IMMEndpoint, (void **) &endpoint);
    if (hr != S_OK)
      goto next;

    hr = IMMEndpoint_GetDataFlow (endpoint, &dataflow);
    if (hr != S_OK)
      goto next;

    if (dataflow == eRender) {
      device_class = "Audio/Sink";
      element_name = "wasapisink";
    } else {
      device_class = "Audio/Source";
      element_name = "wasapisrc";
    }

    PropVariantInit (&var);

    hr = IMMDevice_GetId (item, &wstrid);
    if (hr != S_OK)
      goto next;
    strid = g_utf16_to_utf8 (wstrid, -1, NULL, NULL, NULL);
    CoTaskMemFree (wstrid);

    hr = IMMDevice_OpenPropertyStore (item, STGM_READ, &prop_store);
    if (hr != S_OK)
      goto next;

    /* NOTE: More properties can be added as needed from here:
     * https://msdn.microsoft.com/en-us/library/windows/desktop/dd370794(v=vs.85).aspx */
    hr = IPropertyStore_GetValue (prop_store, &PKEY_Device_FriendlyName, &var);
    if (hr != S_OK)
      goto next;
    description = g_utf16_to_utf8 (var.pwszVal, -1, NULL, NULL, NULL);
    PropVariantClear (&var);

    /* Get the audio client so we can fetch the mix format for shared mode
     * to get the device format for exclusive mode (or something close to that)
     * fetch PKEY_AudioEngine_DeviceFormat from the property store. */
    hr = IMMDevice_Activate (item, &IID_IAudioClient, CLSCTX_ALL, NULL,
        (void **) &client);
    if (hr != S_OK) {
      gchar *msg = gst_wasapi_util_hresult_to_string (hr);
      GST_ERROR_OBJECT (self, "IMMDevice::Activate (IID_IAudioClient) failed"
          "on %s: %s", strid, msg);
      g_free (msg);
      goto next;
    }

    hr = IAudioClient_GetMixFormat (client, &format);
    if (hr != S_OK || format == NULL) {
      gchar *msg = gst_wasapi_util_hresult_to_string (hr);
      GST_ERROR_OBJECT (self, "GetMixFormat failed on %s: %s", strid, msg);
      g_free (msg);
      goto next;
    }

    if (!gst_wasapi_util_parse_waveformatex ((WAVEFORMATEXTENSIBLE *) format,
            gst_static_caps_get (&scaps), &caps, NULL))
      goto next;

    /* Set some useful properties */
    props = gst_structure_new ("wasapi-proplist",
        "device.api", G_TYPE_STRING, "wasapi",
        "device.strid", G_TYPE_STRING, GST_STR_NULL (strid),
        "wasapi.device.description", G_TYPE_STRING, description, NULL);

    device = g_object_new (GST_TYPE_WASAPI_DEVICE, "device", strid,
        "display-name", description, "caps", caps,
        "device-class", device_class, "properties", props, NULL);
    GST_WASAPI_DEVICE (device)->element = element_name;

    gst_structure_free (props);
    gst_caps_unref (caps);
    *devices = g_list_prepend (*devices, device);

  next:
    PropVariantClear (&var);
    if (prop_store)
      IUnknown_Release (prop_store);
    if (endpoint)
      IUnknown_Release (endpoint);
    if (client)
      IUnknown_Release (client);
    if (item)
      IUnknown_Release (item);
    if (description)
      g_free (description);
    if (strid)
      g_free (strid);
  }

  res = TRUE;

err:
  if (enumerator)
    IUnknown_Release (enumerator);
  if (device_collection)
    IUnknown_Release (device_collection);
  return res;
}

gboolean
gst_wasapi_util_get_device_format (GstElement * self,
    gint device_mode, IMMDevice * device, IAudioClient * client,
    WAVEFORMATEX ** ret_format)
{
  WAVEFORMATEX *format;
  HRESULT hr;

  *ret_format = NULL;

  hr = IAudioClient_GetMixFormat (client, &format);
  HR_FAILED_RET (hr, IAudioClient::GetMixFormat, FALSE);

  /* WASAPI always accepts the format returned by GetMixFormat in shared mode */
  if (device_mode == AUDCLNT_SHAREMODE_SHARED)
    goto out;

  /* WASAPI may or may not support this format in exclusive mode */
  hr = IAudioClient_IsFormatSupported (client, AUDCLNT_SHAREMODE_EXCLUSIVE,
      format, NULL);
  if (hr == S_OK)
    goto out;

  CoTaskMemFree (format);

  /* Open the device property store, and get the format that WASAPI has been
   * using for sending data to the device */
  {
    PROPVARIANT var;
    IPropertyStore *prop_store = NULL;

    hr = IMMDevice_OpenPropertyStore (device, STGM_READ, &prop_store);
    HR_FAILED_RET (hr, IMMDevice::OpenPropertyStore, FALSE);

    hr = IPropertyStore_GetValue (prop_store, &PKEY_AudioEngine_DeviceFormat,
        &var);
    if (hr != S_OK) {
      gchar *msg = gst_wasapi_util_hresult_to_string (hr);
      GST_ERROR_OBJECT (self, "GetValue failed: %s", msg);
      g_free (msg);
      IUnknown_Release (prop_store);
      return FALSE;
    }

    format = malloc (var.blob.cbSize);
    memcpy (format, var.blob.pBlobData, var.blob.cbSize);

    PropVariantClear (&var);
    IUnknown_Release (prop_store);
  }

  /* WASAPI may or may not support this format in exclusive mode */
  hr = IAudioClient_IsFormatSupported (client, AUDCLNT_SHAREMODE_EXCLUSIVE,
      format, NULL);
  if (hr == S_OK)
    goto out;

  GST_ERROR_OBJECT (self, "AudioEngine DeviceFormat not supported");
  free (format);
  return FALSE;

out:
  *ret_format = format;
  return TRUE;
}

gboolean
gst_wasapi_util_get_device_client (GstElement * self,
    gboolean capture, gint role, const wchar_t * device_strid,
    IMMDevice ** ret_device, IAudioClient ** ret_client)
{
  gboolean res = FALSE;
  HRESULT hr;
  IMMDeviceEnumerator *enumerator = NULL;
  IMMDevice *device = NULL;
  IAudioClient *client = NULL;

  if (!(enumerator = gst_wasapi_util_get_device_enumerator (self)))
    goto beach;

  if (!device_strid) {
    hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint (enumerator,
        capture ? eCapture : eRender, role, &device);
    HR_FAILED_GOTO (hr, IMMDeviceEnumerator::GetDefaultAudioEndpoint, beach);
  } else {
    hr = IMMDeviceEnumerator_GetDevice (enumerator, device_strid, &device);
    if (hr != S_OK) {
      gchar *msg = gst_wasapi_util_hresult_to_string (hr);
      GST_ERROR_OBJECT (self, "IMMDeviceEnumerator::GetDevice (%S) failed"
          ": %s", device_strid, msg);
      g_free (msg);
      goto beach;
    }
  }

  if (gst_wasapi_util_have_audioclient3 ())
    hr = IMMDevice_Activate (device, &IID_IAudioClient3, CLSCTX_ALL, NULL,
        (void **) &client);
  else
    hr = IMMDevice_Activate (device, &IID_IAudioClient, CLSCTX_ALL, NULL,
        (void **) &client);
  HR_FAILED_GOTO (hr, IMMDevice::Activate (IID_IAudioClient), beach);

  IUnknown_AddRef (client);
  IUnknown_AddRef (device);
  *ret_client = client;
  *ret_device = device;

  res = TRUE;

beach:
  if (client != NULL)
    IUnknown_Release (client);

  if (device != NULL)
    IUnknown_Release (device);

  if (enumerator != NULL)
    IUnknown_Release (enumerator);

  return res;
}

gboolean
gst_wasapi_util_get_render_client (GstElement * self, IAudioClient * client,
    IAudioRenderClient ** ret_render_client)
{
  gboolean res = FALSE;
  HRESULT hr;
  IAudioRenderClient *render_client = NULL;

  hr = IAudioClient_GetService (client, &IID_IAudioRenderClient,
      (void **) &render_client);
  HR_FAILED_GOTO (hr, IAudioClient::GetService, beach);

  *ret_render_client = render_client;
  res = TRUE;

beach:
  return res;
}

gboolean
gst_wasapi_util_get_capture_client (GstElement * self, IAudioClient * client,
    IAudioCaptureClient ** ret_capture_client)
{
  gboolean res = FALSE;
  HRESULT hr;
  IAudioCaptureClient *capture_client = NULL;

  hr = IAudioClient_GetService (client, &IID_IAudioCaptureClient,
      (void **) &capture_client);
  HR_FAILED_GOTO (hr, IAudioClient::GetService, beach);

  *ret_capture_client = capture_client;
  res = TRUE;

beach:
  return res;
}

gboolean
gst_wasapi_util_get_clock (GstElement * self, IAudioClient * client,
    IAudioClock ** ret_clock)
{
  gboolean res = FALSE;
  HRESULT hr;
  IAudioClock *clock = NULL;

  hr = IAudioClient_GetService (client, &IID_IAudioClock, (void **) &clock);
  HR_FAILED_GOTO (hr, IAudioClient::GetService, beach);

  *ret_clock = clock;
  res = TRUE;

beach:
  return res;
}

static const gchar *
gst_waveformatex_to_audio_format (WAVEFORMATEXTENSIBLE * format)
{
  const gchar *fmt_str = NULL;
  GstAudioFormat fmt = GST_AUDIO_FORMAT_UNKNOWN;

  if (format->Format.wFormatTag == WAVE_FORMAT_PCM) {
    fmt = gst_audio_format_build_integer (TRUE, G_LITTLE_ENDIAN,
        format->Format.wBitsPerSample, format->Format.wBitsPerSample);
  } else if (format->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
    if (format->Format.wBitsPerSample == 32)
      fmt = GST_AUDIO_FORMAT_F32LE;
    else if (format->Format.wBitsPerSample == 64)
      fmt = GST_AUDIO_FORMAT_F64LE;
  } else if (format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
    if (IsEqualGUID (&format->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) {
      fmt = gst_audio_format_build_integer (TRUE, G_LITTLE_ENDIAN,
          format->Format.wBitsPerSample, format->Samples.wValidBitsPerSample);
    } else if (IsEqualGUID (&format->SubFormat,
            &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
      if (format->Format.wBitsPerSample == 32
          && format->Samples.wValidBitsPerSample == 32)
        fmt = GST_AUDIO_FORMAT_F32LE;
      else if (format->Format.wBitsPerSample == 64 &&
          format->Samples.wValidBitsPerSample == 64)
        fmt = GST_AUDIO_FORMAT_F64LE;
    }
  }

  if (fmt != GST_AUDIO_FORMAT_UNKNOWN)
    fmt_str = gst_audio_format_to_string (fmt);

  return fmt_str;
}

static void
gst_wasapi_util_channel_position_all_none (guint channels,
    GstAudioChannelPosition * position)
{
  int ii;
  for (ii = 0; ii < channels; ii++)
    position[ii] = GST_AUDIO_CHANNEL_POSITION_NONE;
}

/* Parse WAVEFORMATEX to get the gstreamer channel mask, and the wasapi channel
 * positions so GstAudioRingbuffer can reorder the audio data to match the
 * gstreamer channel order. */
static guint64
gst_wasapi_util_waveformatex_to_channel_mask (WAVEFORMATEXTENSIBLE * format,
    GstAudioChannelPosition ** out_position)
{
  int ii;
  guint64 mask = 0;
  WORD nChannels = format->Format.nChannels;
  DWORD dwChannelMask = format->dwChannelMask;
  GstAudioChannelPosition *pos = NULL;

  pos = g_new (GstAudioChannelPosition, nChannels);
  gst_wasapi_util_channel_position_all_none (nChannels, pos);

  /* Too many channels, have to assume that they are all non-positional */
  if (nChannels > G_N_ELEMENTS (wasapi_to_gst_pos)) {
    GST_INFO ("Got too many (%i) channels, assuming non-positional",
        nChannels);
    goto out;
  }

  /* Too many bits in the channel mask, and the bits don't match nChannels */
  if (dwChannelMask >> (G_N_ELEMENTS (wasapi_to_gst_pos) + 1) != 0) {
    GST_WARNING ("Too many bits in channel mask (%lu), assuming "
        "non-positional", dwChannelMask);
    goto out;
  }

  /* Map WASAPI's channel mask to Gstreamer's channel mask and positions.
   * If the no. of bits in the mask > nChannels, we will ignore the extra. */
  for (ii = 0; ii < nChannels; ii++) {
    if (!(dwChannelMask & wasapi_to_gst_pos[ii].wasapi_pos))
      /* Non-positional or unknown position, warn? */
      continue;
    mask |= G_GUINT64_CONSTANT (1) << wasapi_to_gst_pos[ii].gst_pos;
    pos[ii] = wasapi_to_gst_pos[ii].gst_pos;
  }

out:
  if (out_position)
    *out_position = pos;
  return mask;
}

gboolean
gst_wasapi_util_parse_waveformatex (WAVEFORMATEXTENSIBLE * format,
    GstCaps * template_caps, GstCaps ** out_caps,
    GstAudioChannelPosition ** out_positions)
{
  int ii;
  const gchar *afmt;
  guint64 channel_mask;

  *out_caps = NULL;

  /* TODO: handle SPDIF and other encoded formats */

  /* 1 or 2 channels <= 16 bits sample size OR
   * 1 or 2 channels > 16 bits sample size or >2 channels */
  if (format->Format.wFormatTag != WAVE_FORMAT_PCM &&
      format->Format.wFormatTag != WAVE_FORMAT_IEEE_FLOAT &&
      format->Format.wFormatTag != WAVE_FORMAT_EXTENSIBLE)
    /* Unhandled format tag */
    return FALSE;

  /* WASAPI can only tell us one canonical mix format that it will accept. The
   * alternative is calling IsFormatSupported on all combinations of formats.
   * Instead, it's simpler and faster to require conversion inside gstreamer */
  afmt = gst_waveformatex_to_audio_format (format);
  if (afmt == NULL)
    return FALSE;

  *out_caps = gst_caps_copy (template_caps);

  /* This will always return something that might be usable */
  channel_mask =
      gst_wasapi_util_waveformatex_to_channel_mask (format, out_positions);

  for (ii = 0; ii < gst_caps_get_size (*out_caps); ii++) {
    GstStructure *s = gst_caps_get_structure (*out_caps, ii);

    gst_structure_set (s,
        "format", G_TYPE_STRING, afmt,
        "channels", G_TYPE_INT, format->Format.nChannels,
        "rate", G_TYPE_INT, format->Format.nSamplesPerSec,
        "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL);
  }

  return TRUE;
}

void
gst_wasapi_util_get_best_buffer_sizes (GstAudioRingBufferSpec * spec,
    gboolean exclusive, REFERENCE_TIME default_period,
    REFERENCE_TIME min_period, REFERENCE_TIME * ret_period,
    REFERENCE_TIME * ret_buffer_duration)
{
  REFERENCE_TIME use_period, use_buffer;

  /* Figure out what integral device period to use as the base */
  if (exclusive) {
    /* Exclusive mode can run at multiples of either the minimum period or the
     * default period; these are on the hardware ringbuffer */
    if (spec->latency_time * 10 > default_period)
      use_period = default_period;
    else
      use_period = min_period;
  } else {
    /* Shared mode always runs at the default period, so if we want a larger
     * period (for lower CPU usage), we do it as a multiple of that */
    use_period = default_period;
  }

  /* Ensure that the period (latency_time) used is an integral multiple of
   * either the default period or the minimum period */
  use_period = use_period * MAX ((spec->latency_time * 10) / use_period, 1);

  if (exclusive) {
    /* Buffer duration is the same as the period in exclusive mode. The
     * hardware is always writing out one buffer (of size *ret_period), and
     * we're writing to the other one. */
    use_buffer = use_period;
  } else {
    /* Ask WASAPI to create a software ringbuffer of at least this size; it may
     * be larger so the actual buffer time may be different, which is why after
     * initialization we read the buffer duration actually in-use and set
     * segsize/segtotal from that. */
    use_buffer = spec->buffer_time * 10;
    /* Has to be at least twice the period */
    if (use_buffer < 2 * use_period)
      use_buffer = 2 * use_period;
  }

  *ret_period = use_period;
  *ret_buffer_duration = use_buffer;
}

gboolean
gst_wasapi_util_initialize_audioclient (GstElement * self,
    GstAudioRingBufferSpec * spec, IAudioClient * client,
    WAVEFORMATEX * format, guint sharemode, gboolean low_latency,
    guint * ret_devicep_frames)
{
  REFERENCE_TIME default_period, min_period;
  REFERENCE_TIME device_period, device_buffer_duration;
  guint rate;
  HRESULT hr;

  hr = IAudioClient_GetDevicePeriod (client, &default_period, &min_period);
  HR_FAILED_RET (hr, IAudioClient::GetDevicePeriod, FALSE);

  GST_INFO_OBJECT (self, "wasapi default period: %" G_GINT64_FORMAT
      ", min period: %" G_GINT64_FORMAT, default_period, min_period);

  rate = GST_AUDIO_INFO_RATE (&spec->info);

  if (low_latency) {
    if (sharemode == AUDCLNT_SHAREMODE_SHARED) {
      device_period = default_period;
      device_buffer_duration = 0;
    } else {
      device_period = min_period;
      device_buffer_duration = min_period;
    }
  } else {
    /* Clamp values to integral multiples of an appropriate period */
    gst_wasapi_util_get_best_buffer_sizes (spec,
        sharemode == AUDCLNT_SHAREMODE_EXCLUSIVE, default_period,
        min_period, &device_period, &device_buffer_duration);
  }

  /* For some reason, we need to call this a second time for exclusive mode */
  if (sharemode == AUDCLNT_SHAREMODE_EXCLUSIVE)
    CoInitialize (NULL);

  hr = IAudioClient_Initialize (client, sharemode,
      AUDCLNT_STREAMFLAGS_EVENTCALLBACK, device_buffer_duration,
      /* This must always be 0 in shared mode */
      sharemode == AUDCLNT_SHAREMODE_SHARED ? 0 : device_period, format, NULL);

  if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED &&
      sharemode == AUDCLNT_SHAREMODE_EXCLUSIVE) {
    guint32 n_frames;

    GST_WARNING_OBJECT (self, "initialize failed due to unaligned period %i",
        (int) device_period);

    /* Calculate a new aligned period. First get the aligned buffer size. */
    hr = IAudioClient_GetBufferSize (client, &n_frames);
    HR_FAILED_RET (hr, IAudioClient::GetBufferSize, FALSE);

    device_period = (GST_SECOND / 100) * n_frames / rate;

    GST_WARNING_OBJECT (self, "trying to re-initialize with period %i "
        "(%i frames, %i rate)", (int) device_period, n_frames, rate);

    hr = IAudioClient_Initialize (client, sharemode,
        AUDCLNT_STREAMFLAGS_EVENTCALLBACK, device_period,
        device_period, format, NULL);
  }
  HR_FAILED_RET (hr, IAudioClient::Initialize, FALSE);

  *ret_devicep_frames = (rate * device_period * 100) / GST_SECOND;

  return TRUE;
}

gboolean
gst_wasapi_util_initialize_audioclient3 (GstElement * self,
    GstAudioRingBufferSpec * spec, IAudioClient3 * client,
    WAVEFORMATEX * format, gboolean low_latency, guint * ret_devicep_frames)
{
  HRESULT hr;
  guint rate, devicep_frames;
  guint defaultp_frames, fundp_frames, minp_frames, maxp_frames;
  WAVEFORMATEX *tmpf;

  rate = GST_AUDIO_INFO_RATE (&spec->info);

  hr = IAudioClient3_GetSharedModeEnginePeriod (client, format,
      &defaultp_frames, &fundp_frames, &minp_frames, &maxp_frames);
  HR_FAILED_RET (hr, IAudioClient3::GetSharedModeEnginePeriod, FALSE);

  GST_INFO_OBJECT (self, "Using IAudioClient3, default period %i frames, "
      "fundamental period %i frames, minimum period %i frames, maximum period "
      "%i frames", defaultp_frames, fundp_frames, minp_frames, maxp_frames);

  if (low_latency) {
    devicep_frames = minp_frames;
  } else {
    /* rate is in Hz, latency_time is in usec */
    int tmp = (rate * spec->latency_time * GST_USECOND) / GST_SECOND;
    devicep_frames = CLAMP (tmp, minp_frames, maxp_frames);
    /* Ensure it's a multiple of the fundamental period */
    tmp = devicep_frames / fundp_frames;
    devicep_frames = tmp * fundp_frames;
  }

  hr = IAudioClient3_InitializeSharedAudioStream (client,
      AUDCLNT_STREAMFLAGS_EVENTCALLBACK, devicep_frames, format, NULL);
  HR_FAILED_RET (hr, IAudioClient3::InitializeSharedAudioStream, FALSE);

  hr = IAudioClient3_GetCurrentSharedModeEnginePeriod (client, &tmpf,
      &devicep_frames);
  CoTaskMemFree (tmpf);
  HR_FAILED_RET (hr, IAudioClient3::GetCurrentSharedModeEnginePeriod, FALSE);

  *ret_devicep_frames = devicep_frames;
  return TRUE;
}

static gboolean
gst_wasapi_util_init_thread_priority (void)
{
  if (gst_wasapi_avrt_tbl.tried_loading)
    return gst_wasapi_avrt_tbl.dll != NULL;

  if (!gst_wasapi_avrt_tbl.dll)
    gst_wasapi_avrt_tbl.dll = LoadLibrary (TEXT ("avrt.dll"));

  if (!gst_wasapi_avrt_tbl.dll) {
    GST_WARNING ("Failed to set thread priority, can't find avrt.dll");
    gst_wasapi_avrt_tbl.tried_loading = TRUE;
    return FALSE;
  }

  gst_wasapi_avrt_tbl.AvSetMmThreadCharacteristics =
      GetProcAddress (gst_wasapi_avrt_tbl.dll, "AvSetMmThreadCharacteristicsA");
  gst_wasapi_avrt_tbl.AvRevertMmThreadCharacteristics =
      GetProcAddress (gst_wasapi_avrt_tbl.dll,
      "AvRevertMmThreadCharacteristics");

  gst_wasapi_avrt_tbl.tried_loading = TRUE;

  return TRUE;
}

HANDLE
gst_wasapi_util_set_thread_characteristics (void)
{
  DWORD taskIndex = 0;

  if (!gst_wasapi_util_init_thread_priority ())
    return NULL;

  return gst_wasapi_avrt_tbl.AvSetMmThreadCharacteristics (TEXT ("Pro Audio"),
      &taskIndex);
}

void
gst_wasapi_util_revert_thread_characteristics (HANDLE handle)
{
  if (!gst_wasapi_util_init_thread_priority ())
    return;

  gst_wasapi_avrt_tbl.AvRevertMmThreadCharacteristics (handle);
}
