/*
 * 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 <initguid.h>
#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 ("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 ("wasapi: 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 ("wasapi: 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);
}
