/*
 * GStreamer
 * Copyright (C) 2012-2013 Fluendo S.A. <support@fluendo.com>
 *   Authors: Josep Torra Vallès <josep@fluendo.com>
 *            Andoni Morales Alastruey <amorales@fluendo.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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */

#include <unistd.h>             /* for getpid */
#include "gstosxaudiosink.h"

static inline gboolean
_audio_system_set_runloop (CFRunLoopRef runLoop)
{
  OSStatus status = noErr;

  gboolean res = FALSE;

  AudioObjectPropertyAddress runloopAddress = {
    kAudioHardwarePropertyRunLoop,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectSetPropertyData (kAudioObjectSystemObject,
      &runloopAddress, 0, NULL, sizeof (CFRunLoopRef), &runLoop);
  if (status == noErr) {
    res = TRUE;
  } else {
    GST_ERROR ("failed to set runloop to %p: %" GST_FOURCC_FORMAT,
        runLoop, GST_FOURCC_ARGS (status));
  }

  return res;
}

static inline AudioDeviceID
_audio_system_get_default_output (void)
{
  OSStatus status = noErr;
  UInt32 propertySize = sizeof (AudioDeviceID);
  AudioDeviceID device_id = kAudioDeviceUnknown;

  AudioObjectPropertyAddress defaultDeviceAddress = {
    kAudioHardwarePropertyDefaultOutputDevice,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyData (kAudioObjectSystemObject,
      &defaultDeviceAddress, 0, NULL, &propertySize, &device_id);
  if (status != noErr) {
    GST_ERROR ("failed getting default output device: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
  }

  return device_id;
}

static inline AudioDeviceID *
_audio_system_get_devices (gint * ndevices)
{
  OSStatus status = noErr;
  UInt32 propertySize = 0;
  AudioDeviceID *devices = NULL;

  AudioObjectPropertyAddress audioDevicesAddress = {
    kAudioHardwarePropertyDevices,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyDataSize (kAudioObjectSystemObject,
      &audioDevicesAddress, 0, NULL, &propertySize);
  if (status != noErr) {
    GST_WARNING ("failed getting number of devices: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
    return NULL;
  }

  *ndevices = propertySize / sizeof (AudioDeviceID);

  devices = (AudioDeviceID *) g_malloc (propertySize);
  if (devices) {
    status = AudioObjectGetPropertyData (kAudioObjectSystemObject,
        &audioDevicesAddress, 0, NULL, &propertySize, devices);
    if (status != noErr) {
      GST_WARNING ("failed getting the list of devices: %"
          GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
      g_free (devices);
      *ndevices = 0;
      return NULL;
    }
  }
  return devices;
}

static inline gboolean
_audio_device_is_alive (AudioDeviceID device_id)
{
  OSStatus status = noErr;
  int alive = FALSE;
  UInt32 propertySize = sizeof (alive);

  AudioObjectPropertyAddress audioDeviceAliveAddress = {
    kAudioDevicePropertyDeviceIsAlive,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyData (device_id,
      &audioDeviceAliveAddress, 0, NULL, &propertySize, &alive);
  if (status != noErr) {
    alive = FALSE;
  }

  return alive;
}

static inline guint
_audio_device_get_latency (AudioDeviceID device_id)
{
  OSStatus status = noErr;
  UInt32 latency = 0;
  UInt32 propertySize = sizeof (latency);

  AudioObjectPropertyAddress audioDeviceLatencyAddress = {
    kAudioDevicePropertyLatency,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyData (device_id,
      &audioDeviceLatencyAddress, 0, NULL, &propertySize, &latency);
  if (status != noErr) {
    GST_ERROR ("failed to get latency: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
    latency = -1;
  }

  return latency;
}

static inline pid_t
_audio_device_get_hog (AudioDeviceID device_id)
{
  OSStatus status = noErr;
  pid_t hog_pid;
  UInt32 propertySize = sizeof (hog_pid);

  AudioObjectPropertyAddress audioDeviceHogModeAddress = {
    kAudioDevicePropertyHogMode,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyData (device_id,
      &audioDeviceHogModeAddress, 0, NULL, &propertySize, &hog_pid);
  if (status != noErr) {
    GST_ERROR ("failed to get hog: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
    hog_pid = -1;
  }

  return hog_pid;
}

static inline gboolean
_audio_device_set_hog (AudioDeviceID device_id, pid_t hog_pid)
{
  OSStatus status = noErr;
  UInt32 propertySize = sizeof (hog_pid);
  gboolean res = FALSE;

  AudioObjectPropertyAddress audioDeviceHogModeAddress = {
    kAudioDevicePropertyHogMode,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectSetPropertyData (device_id,
      &audioDeviceHogModeAddress, 0, NULL, propertySize, &hog_pid);

  if (status == noErr) {
    res = TRUE;
  } else {
    GST_ERROR ("failed to set hog: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
  }

  return res;
}

static inline gboolean
_audio_device_set_mixing (AudioDeviceID device_id, gboolean enable_mix)
{
  OSStatus status = noErr;
  UInt32 propertySize = 0, can_mix = enable_mix;
  Boolean writable = FALSE;
  gboolean res = FALSE;

  AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = {
    kAudioDevicePropertySupportsMixing,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  if (AudioObjectHasProperty (device_id, &audioDeviceSupportsMixingAddress)) {
    /* Set mixable to false if we are allowed to */
    status = AudioObjectIsPropertySettable (device_id,
        &audioDeviceSupportsMixingAddress, &writable);
    if (status) {
      GST_DEBUG ("AudioObjectIsPropertySettable: %" GST_FOURCC_FORMAT,
          GST_FOURCC_ARGS (status));
    }
    status = AudioObjectGetPropertyDataSize (device_id,
        &audioDeviceSupportsMixingAddress, 0, NULL, &propertySize);
    if (status) {
      GST_DEBUG ("AudioObjectGetPropertyDataSize: %" GST_FOURCC_FORMAT,
          GST_FOURCC_ARGS (status));
    }
    status = AudioObjectGetPropertyData (device_id,
        &audioDeviceSupportsMixingAddress, 0, NULL, &propertySize, &can_mix);
    if (status) {
      GST_DEBUG ("AudioObjectGetPropertyData: %" GST_FOURCC_FORMAT,
          GST_FOURCC_ARGS (status));
    }

    if (status == noErr && writable) {
      can_mix = enable_mix;
      status = AudioObjectSetPropertyData (device_id,
          &audioDeviceSupportsMixingAddress, 0, NULL, propertySize, &can_mix);
      res = TRUE;
    }

    if (status != noErr) {
      GST_ERROR ("failed to set mixmode: %" GST_FOURCC_FORMAT,
          GST_FOURCC_ARGS (status));
    }
  } else {
    GST_DEBUG ("property not found, mixing coudln't be changed");
  }

  return res;
}

static inline gchar *
_audio_device_get_name (AudioDeviceID device_id)
{
  OSStatus status = noErr;
  UInt32 propertySize = 0;
  gchar *device_name = NULL;

  AudioObjectPropertyAddress deviceNameAddress = {
    kAudioDevicePropertyDeviceName,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  /* Get the length of the device name */
  status = AudioObjectGetPropertyDataSize (device_id,
      &deviceNameAddress, 0, NULL, &propertySize);
  if (status != noErr) {
    goto beach;
  }

  /* Get the name of the device */
  device_name = (gchar *) g_malloc (propertySize);
  status = AudioObjectGetPropertyData (device_id,
      &deviceNameAddress, 0, NULL, &propertySize, device_name);
  if (status != noErr) {
    g_free (device_name);
    device_name = NULL;
  }

beach:
  return device_name;
}

static inline gboolean
_audio_device_has_output (AudioDeviceID device_id)
{
  OSStatus status = noErr;
  UInt32 propertySize;

  AudioObjectPropertyAddress streamsAddress = {
    kAudioDevicePropertyStreams,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyDataSize (device_id,
      &streamsAddress, 0, NULL, &propertySize);
  if (status != noErr) {
    return FALSE;
  }
  if (propertySize == 0) {
    return FALSE;
  }

  return TRUE;
}

AudioChannelLayout *
gst_core_audio_audio_device_get_channel_layout (AudioDeviceID device_id)
{
  OSStatus status = noErr;
  UInt32 propertySize = 0;
  AudioChannelLayout *layout = NULL;

  AudioObjectPropertyAddress channelLayoutAddress = {
    kAudioDevicePropertyPreferredChannelLayout,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  /* Get the length of the default channel layout structure */
  status = AudioObjectGetPropertyDataSize (device_id,
      &channelLayoutAddress, 0, NULL, &propertySize);
  if (status != noErr) {
    GST_ERROR ("failed to get prefered layout: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
    goto beach;
  }

  /* Get the default channel layout of the device */
  layout = (AudioChannelLayout *) g_malloc (propertySize);
  status = AudioObjectGetPropertyData (device_id,
      &channelLayoutAddress, 0, NULL, &propertySize, layout);
  if (status != noErr) {
    GST_ERROR ("failed to get prefered layout: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
    goto failed;
  }

  if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) {
    /* bitmap defined channellayout */
    status =
        AudioFormatGetProperty (kAudioFormatProperty_ChannelLayoutForBitmap,
        sizeof (UInt32), &layout->mChannelBitmap, &propertySize, layout);
    if (status != noErr) {
      GST_ERROR ("failed to get layout for bitmap: %" GST_FOURCC_FORMAT,
          GST_FOURCC_ARGS (status));
      goto failed;
    }
  } else if (layout->mChannelLayoutTag !=
      kAudioChannelLayoutTag_UseChannelDescriptions) {
    /* layouttags defined channellayout */
    status = AudioFormatGetProperty (kAudioFormatProperty_ChannelLayoutForTag,
        sizeof (AudioChannelLayoutTag), &layout->mChannelLayoutTag,
        &propertySize, layout);
    if (status != noErr) {
      GST_ERROR ("failed to get layout for tag: %" GST_FOURCC_FORMAT,
          GST_FOURCC_ARGS (status));
      goto failed;
    }
  }

  gst_core_audio_dump_channel_layout (layout);

beach:
  return layout;

failed:
  g_free (layout);
  return NULL;
}

static inline AudioStreamID *
_audio_device_get_streams (AudioDeviceID device_id, gint * nstreams)
{
  OSStatus status = noErr;
  UInt32 propertySize = 0;
  AudioStreamID *streams = NULL;

  AudioObjectPropertyAddress streamsAddress = {
    kAudioDevicePropertyStreams,
    kAudioDevicePropertyScopeOutput,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyDataSize (device_id,
      &streamsAddress, 0, NULL, &propertySize);
  if (status != noErr) {
    GST_WARNING ("failed getting number of streams: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
    return NULL;
  }

  *nstreams = propertySize / sizeof (AudioStreamID);
  streams = (AudioStreamID *) g_malloc (propertySize);

  if (streams) {
    status = AudioObjectGetPropertyData (device_id,
        &streamsAddress, 0, NULL, &propertySize, streams);
    if (status != noErr) {
      GST_WARNING ("failed getting the list of streams: %"
          GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
      g_free (streams);
      *nstreams = 0;
      return NULL;
    }
  }

  return streams;
}

static inline guint
_audio_stream_get_latency (AudioStreamID stream_id)
{
  OSStatus status = noErr;
  UInt32 latency;
  UInt32 propertySize = sizeof (latency);

  AudioObjectPropertyAddress latencyAddress = {
    kAudioStreamPropertyLatency,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyData (stream_id,
      &latencyAddress, 0, NULL, &propertySize, &latency);
  if (status != noErr) {
    GST_ERROR ("failed to get latency: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
    latency = -1;
  }

  return latency;
}

static inline gboolean
_audio_stream_get_current_format (AudioStreamID stream_id,
    AudioStreamBasicDescription * format)
{
  OSStatus status = noErr;
  UInt32 propertySize = sizeof (AudioStreamBasicDescription);

  AudioObjectPropertyAddress formatAddress = {
    kAudioStreamPropertyPhysicalFormat,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyData (stream_id,
      &formatAddress, 0, NULL, &propertySize, format);
  if (status != noErr) {
    GST_ERROR ("failed to get current format: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
    return FALSE;
  }

  return TRUE;
}

static inline gboolean
_audio_stream_set_current_format (AudioStreamID stream_id,
    AudioStreamBasicDescription format)
{
  OSStatus status = noErr;
  UInt32 propertySize = sizeof (AudioStreamBasicDescription);

  AudioObjectPropertyAddress formatAddress = {
    kAudioStreamPropertyPhysicalFormat,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectSetPropertyData (stream_id,
      &formatAddress, 0, NULL, propertySize, &format);
  if (status != noErr) {
    GST_ERROR ("failed to set current format: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
    return FALSE;
  }

  return TRUE;
}

static inline AudioStreamRangedDescription *
_audio_stream_get_formats (AudioStreamID stream_id, gint * nformats)
{
  OSStatus status = noErr;
  UInt32 propertySize = 0;
  AudioStreamRangedDescription *formats = NULL;

  AudioObjectPropertyAddress formatsAddress = {
    kAudioStreamPropertyAvailablePhysicalFormats,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  status = AudioObjectGetPropertyDataSize (stream_id,
      &formatsAddress, 0, NULL, &propertySize);
  if (status != noErr) {
    GST_WARNING ("failed getting number of stream formats: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
    return NULL;
  }

  *nformats = propertySize / sizeof (AudioStreamRangedDescription);

  formats = (AudioStreamRangedDescription *) g_malloc (propertySize);
  if (formats) {
    status = AudioObjectGetPropertyData (stream_id,
        &formatsAddress, 0, NULL, &propertySize, formats);
    if (status != noErr) {
      GST_WARNING ("failed getting the list of stream formats: %"
          GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
      g_free (formats);
      *nformats = 0;
      return NULL;
    }
  }
  return formats;
}

static inline gboolean
_audio_stream_is_spdif_avail (AudioStreamID stream_id)
{
  AudioStreamRangedDescription *formats;
  gint i, nformats = 0;
  gboolean res = FALSE;

  formats = _audio_stream_get_formats (stream_id, &nformats);
  GST_DEBUG ("found %d stream formats", nformats);

  if (formats) {
    GST_DEBUG ("formats supported on stream ID: %u", (unsigned) stream_id);

    for (i = 0; i < nformats; i++) {
      GST_DEBUG ("  " CORE_AUDIO_FORMAT,
          CORE_AUDIO_FORMAT_ARGS (formats[i].mFormat));

      if (CORE_AUDIO_FORMAT_IS_SPDIF (formats[i])) {
        res = TRUE;
      }
    }
    g_free (formats);
  }

  return res;
}

static OSStatus
_audio_stream_format_listener (AudioObjectID inObjectID,
    UInt32 inNumberAddresses,
    const AudioObjectPropertyAddress inAddresses[], void *inClientData)
{
  OSStatus status = noErr;
  guint i;
  PropertyMutex *prop_mutex = inClientData;

  for (i = 0; i < inNumberAddresses; i++) {
    if (inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat) {
      g_mutex_lock (&prop_mutex->lock);
      g_cond_signal (&prop_mutex->cond);
      g_mutex_unlock (&prop_mutex->lock);
      break;
    }
  }
  return (status);
}

static gboolean
_audio_stream_change_format (AudioStreamID stream_id,
    AudioStreamBasicDescription format)
{
  OSStatus status = noErr;
  gint i;
  gboolean ret = FALSE;
  AudioStreamBasicDescription cformat;
  PropertyMutex prop_mutex;

  AudioObjectPropertyAddress formatAddress = {
    kAudioStreamPropertyPhysicalFormat,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  GST_DEBUG ("setting stream format: " CORE_AUDIO_FORMAT,
      CORE_AUDIO_FORMAT_ARGS (format));

  /* Condition because SetProperty is asynchronous */
  g_mutex_init (&prop_mutex.lock);
  g_cond_init (&prop_mutex.cond);

  g_mutex_lock (&prop_mutex.lock);

  /* Install the property listener to serialize the operations */
  status = AudioObjectAddPropertyListener (stream_id, &formatAddress,
      _audio_stream_format_listener, (void *) &prop_mutex);
  if (status != noErr) {
    GST_ERROR ("AudioObjectAddPropertyListener failed: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
    goto done;
  }

  /* Change the format */
  if (!_audio_stream_set_current_format (stream_id, format)) {
    goto done;
  }

  /* The AudioObjectSetProperty is not only asynchronous
   * it is also not atomic in its behaviour.
   * Therefore we check 4 times before we really give up. */
  for (i = 0; i < 4; i++) {
    GTimeVal timeout;

    g_get_current_time (&timeout);
    g_time_val_add (&timeout, 250000);

    if (!g_cond_wait_until (&prop_mutex.cond, &prop_mutex.lock, timeout.tv_sec)) {
      GST_LOG ("timeout...");
    }

    if (_audio_stream_get_current_format (stream_id, &cformat)) {
      GST_DEBUG ("current stream format: " CORE_AUDIO_FORMAT,
          CORE_AUDIO_FORMAT_ARGS (cformat));

      if (cformat.mSampleRate == format.mSampleRate &&
          cformat.mFormatID == format.mFormatID &&
          cformat.mFramesPerPacket == format.mFramesPerPacket) {
        /* The right format is now active */
        break;
      }
    }
  }

  if (cformat.mSampleRate != format.mSampleRate ||
      cformat.mFormatID != format.mFormatID ||
      cformat.mFramesPerPacket != format.mFramesPerPacket) {
    goto done;
  }

  ret = TRUE;

done:
  /* Removing the property listener */
  status = AudioObjectRemovePropertyListener (stream_id,
      &formatAddress, _audio_stream_format_listener, (void *) &prop_mutex);
  if (status != noErr) {
    GST_ERROR ("AudioObjectRemovePropertyListener failed: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
  }
  /* Destroy the lock and condition */
  g_mutex_unlock (&prop_mutex.lock);
  g_mutex_clear (&prop_mutex.lock);
  g_cond_clear (&prop_mutex.cond);

  return ret;
}

static OSStatus
_audio_stream_hardware_changed_listener (AudioObjectID inObjectID,
    UInt32 inNumberAddresses,
    const AudioObjectPropertyAddress inAddresses[], void *inClientData)
{
  OSStatus status = noErr;
  guint i;
  GstCoreAudio *core_audio = inClientData;

  for (i = 0; i < inNumberAddresses; i++) {
    if (inAddresses[i].mSelector == kAudioDevicePropertyDeviceHasChanged) {
      if (!gst_core_audio_audio_device_is_spdif_avail (core_audio->device_id)) {
        GstOsxAudioSink *sink =
            GST_OSX_AUDIO_SINK (GST_OBJECT_PARENT (core_audio->osxbuf));
        GST_ELEMENT_ERROR (sink, RESOURCE, FAILED,
            ("SPDIF output no longer available"),
            ("Audio device is reporting that SPDIF output isn't available"));
      }
      break;
    }
  }
  return (status);
}

static inline gboolean
_monitorize_spdif (GstCoreAudio * core_audio)
{
  OSStatus status = noErr;
  gboolean ret = TRUE;

  AudioObjectPropertyAddress propAddress = {
    kAudioDevicePropertyDeviceHasChanged,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  /* Install the property listener */
  status = AudioObjectAddPropertyListener (core_audio->device_id,
      &propAddress, _audio_stream_hardware_changed_listener,
      (void *) core_audio);
  if (status != noErr) {
    GST_ERROR_OBJECT (core_audio->osxbuf,
        "AudioObjectAddPropertyListener failed: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
    ret = FALSE;
  }

  return ret;
}

static inline gboolean
_unmonitorize_spdif (GstCoreAudio * core_audio)
{
  OSStatus status = noErr;
  gboolean ret = TRUE;

  AudioObjectPropertyAddress propAddress = {
    kAudioDevicePropertyDeviceHasChanged,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
  };

  /* Remove the property listener */
  status = AudioObjectRemovePropertyListener (core_audio->device_id,
      &propAddress, _audio_stream_hardware_changed_listener,
      (void *) core_audio);
  if (status != noErr) {
    GST_ERROR_OBJECT (core_audio->osxbuf,
        "AudioObjectRemovePropertyListener failed: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
    ret = FALSE;
  }

  return ret;
}

static inline gboolean
_open_spdif (GstCoreAudio * core_audio)
{
  gboolean res = FALSE;
  pid_t hog_pid, own_pid = getpid ();

  /* We need the device in exclusive and disable the mixing */
  hog_pid = _audio_device_get_hog (core_audio->device_id);

  if (hog_pid != -1 && hog_pid != own_pid) {
    GST_DEBUG_OBJECT (core_audio,
        "device is currently in use by another application");
    goto done;
  }

  if (_audio_device_set_hog (core_audio->device_id, own_pid)) {
    core_audio->hog_pid = own_pid;
  }

  if (_audio_device_set_mixing (core_audio->device_id, FALSE)) {
    GST_DEBUG_OBJECT (core_audio, "disabled mixing on the device");
    core_audio->disabled_mixing = TRUE;
  }

  res = TRUE;
done:
  return res;
}

static inline gboolean
_close_spdif (GstCoreAudio * core_audio)
{
  pid_t hog_pid;

  _unmonitorize_spdif (core_audio);

  if (core_audio->revert_format) {
    if (!_audio_stream_change_format (core_audio->stream_id,
            core_audio->original_format)) {
      GST_WARNING_OBJECT (core_audio->osxbuf, "Format revert failed");
    }
    core_audio->revert_format = FALSE;
  }

  if (core_audio->disabled_mixing) {
    _audio_device_set_mixing (core_audio->device_id, TRUE);
    core_audio->disabled_mixing = FALSE;
  }

  if (core_audio->hog_pid != -1) {
    hog_pid = _audio_device_get_hog (core_audio->device_id);
    if (hog_pid == getpid ()) {
      if (_audio_device_set_hog (core_audio->device_id, -1)) {
        core_audio->hog_pid = -1;
      }
    }
  }

  return TRUE;
}

static OSStatus
_io_proc_spdif (AudioDeviceID inDevice,
    const AudioTimeStamp * inNow,
    const void *inInputData,
    const AudioTimeStamp * inTimestamp,
    AudioBufferList * bufferList,
    const AudioTimeStamp * inOutputTime, GstCoreAudio * core_audio)
{
  OSStatus status;

  status = core_audio->element->io_proc (core_audio->osxbuf, NULL, inTimestamp,
      0, 0, bufferList);

  return status;
}

static inline gboolean
_acquire_spdif (GstCoreAudio * core_audio, AudioStreamBasicDescription format)
{
  AudioStreamID *streams = NULL;
  gint i, j, nstreams = 0;
  gboolean ret = FALSE;

  if (!_open_spdif (core_audio))
    goto done;

  streams = _audio_device_get_streams (core_audio->device_id, &nstreams);

  for (i = 0; i < nstreams; i++) {
    AudioStreamRangedDescription *formats = NULL;
    gint nformats = 0;

    formats = _audio_stream_get_formats (streams[i], &nformats);

    if (formats) {
      gboolean is_spdif = FALSE;

      /* Check if one of the supported formats is a digital format */
      for (j = 0; j < nformats; j++) {
        if (CORE_AUDIO_FORMAT_IS_SPDIF (formats[j])) {
          is_spdif = TRUE;
          break;
        }
      }

      if (is_spdif) {
        /* if this stream supports a digital (cac3) format,
         * then go set it. */
        gint requested_rate_format = -1;
        gint current_rate_format = -1;
        gint backup_rate_format = -1;

        core_audio->stream_id = streams[i];
        core_audio->stream_idx = i;

        if (!core_audio->revert_format) {
          if (!_audio_stream_get_current_format (core_audio->stream_id,
                  &core_audio->original_format)) {
            GST_WARNING_OBJECT (core_audio->osxbuf,
                "format could not be saved");
            g_free (formats);
            continue;
          }
          core_audio->revert_format = TRUE;
        }

        for (j = 0; j < nformats; j++) {
          if (CORE_AUDIO_FORMAT_IS_SPDIF (formats[j])) {
            GST_LOG_OBJECT (core_audio->osxbuf,
                "found stream format: " CORE_AUDIO_FORMAT,
                CORE_AUDIO_FORMAT_ARGS (formats[j].mFormat));

            if (formats[j].mFormat.mSampleRate == format.mSampleRate) {
              requested_rate_format = j;
              break;
            } else if (formats[j].mFormat.mSampleRate ==
                core_audio->original_format.mSampleRate) {
              current_rate_format = j;
            } else {
              if (backup_rate_format < 0 ||
                  formats[j].mFormat.mSampleRate >
                  formats[backup_rate_format].mFormat.mSampleRate) {
                backup_rate_format = j;
              }
            }
          }
        }

        if (requested_rate_format >= 0) {
          /* We prefer to output at the rate of the original audio */
          core_audio->stream_format = formats[requested_rate_format].mFormat;
        } else if (current_rate_format >= 0) {
          /* If not possible, we will try to use the current rate */
          core_audio->stream_format = formats[current_rate_format].mFormat;
        } else {
          /* And if we have to, any digital format will be just
           * fine (highest rate possible) */
          core_audio->stream_format = formats[backup_rate_format].mFormat;
        }
      }
      g_free (formats);
    }
  }
  g_free (streams);

  GST_DEBUG_OBJECT (core_audio,
      "original stream format: " CORE_AUDIO_FORMAT,
      CORE_AUDIO_FORMAT_ARGS (core_audio->original_format));

  if (!_audio_stream_change_format (core_audio->stream_id,
          core_audio->stream_format))
    goto done;

  ret = TRUE;

done:
  return ret;
}

static inline void
_remove_render_spdif_callback (GstCoreAudio * core_audio)
{
  OSStatus status;

  /* Deactivate the render callback by calling
   * AudioDeviceDestroyIOProcID */
  status =
      AudioDeviceDestroyIOProcID (core_audio->device_id, core_audio->procID);
  if (status != noErr) {
    GST_ERROR_OBJECT (core_audio->osxbuf,
        "AudioDeviceDestroyIOProcID failed: %"
        GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
  }

  GST_DEBUG_OBJECT (core_audio,
      "osx ring buffer removed ioproc ID: %p device_id %lu",
      core_audio->procID, (gulong) core_audio->device_id);

  /* We're deactivated.. */
  core_audio->procID = 0;
  core_audio->io_proc_needs_deactivation = FALSE;
  core_audio->io_proc_active = FALSE;
}

static inline gboolean
_io_proc_spdif_start (GstCoreAudio * core_audio)
{
  OSErr status;

  GST_DEBUG_OBJECT (core_audio,
      "osx ring buffer start ioproc ID: %p device_id %lu",
      core_audio->procID, (gulong) core_audio->device_id);

  if (!core_audio->io_proc_active) {
    /* Add IOProc callback */
    status = AudioDeviceCreateIOProcID (core_audio->device_id,
        (AudioDeviceIOProc) _io_proc_spdif,
        (void *) core_audio, &core_audio->procID);
    if (status != noErr) {
      GST_ERROR_OBJECT (core_audio->osxbuf,
          ":AudioDeviceCreateIOProcID failed: %"
          GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
      return FALSE;
    }
    core_audio->io_proc_active = TRUE;
  }

  core_audio->io_proc_needs_deactivation = FALSE;

  /* Start device */
  status = AudioDeviceStart (core_audio->device_id, core_audio->procID);
  if (status != noErr) {
    GST_ERROR_OBJECT (core_audio->osxbuf,
        "AudioDeviceStart failed: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
    return FALSE;
  }
  return TRUE;
}

static inline gboolean
_io_proc_spdif_stop (GstCoreAudio * core_audio)
{
  OSErr status;

  /* Stop device */
  status = AudioDeviceStop (core_audio->device_id, core_audio->procID);
  if (status != noErr) {
    GST_ERROR_OBJECT (core_audio->osxbuf,
        "AudioDeviceStop failed: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (status));
  }

  GST_DEBUG_OBJECT (core_audio,
      "osx ring buffer stop ioproc ID: %p device_id %lu",
      core_audio->procID, (gulong) core_audio->device_id);

  if (core_audio->io_proc_active) {
    _remove_render_spdif_callback (core_audio);
  }

  _close_spdif (core_audio);

  return TRUE;
}


/***********************
 *   Implementation    *
 **********************/

static gboolean
gst_core_audio_open_impl (GstCoreAudio * core_audio)
{
  /* The following is needed to instruct HAL to create their own
   * thread to handle the notifications. */
  _audio_system_set_runloop (NULL);

  /* Create a HALOutput AudioUnit.
   * This is the lowest-level output API that is actually sensibly
   * usable (the lower level ones require that you do
   * channel-remapping yourself, and the CoreAudio channel mapping
   * is sufficiently complex that doing so would be very difficult)
   *
   * Note that for input we request an output unit even though
   * we will do input with it.
   * http://developer.apple.com/technotes/tn2002/tn2091.html
   */
  return gst_core_audio_open_device (core_audio, kAudioUnitSubType_HALOutput,
      "HALOutput");
}

static gboolean
gst_core_audio_start_processing_impl (GstCoreAudio * core_audio)
{
  if (core_audio->is_passthrough) {
    return _io_proc_spdif_start (core_audio);
  } else {
    return gst_core_audio_io_proc_start (core_audio);
  }
}

static gboolean
gst_core_audio_pause_processing_impl (GstCoreAudio * core_audio)
{
  if (core_audio->is_passthrough) {
    GST_DEBUG_OBJECT (core_audio,
        "osx ring buffer pause ioproc ID: %p device_id %lu",
        core_audio->procID, (gulong) core_audio->device_id);

    if (core_audio->io_proc_active) {
      _remove_render_spdif_callback (core_audio);
    }
  } else {
    GST_DEBUG_OBJECT (core_audio,
        "osx ring buffer pause ioproc: %p device_id %lu",
        core_audio->element->io_proc, (gulong) core_audio->device_id);
    if (core_audio->io_proc_active) {
      /* CoreAudio isn't threadsafe enough to do this here;
       * we must deactivate the render callback elsewhere. See:
       * http://lists.apple.com/archives/Coreaudio-api/2006/Mar/msg00010.html
       */
      core_audio->io_proc_needs_deactivation = TRUE;
    }
  }
  return TRUE;
}

static gboolean
gst_core_audio_stop_processing_impl (GstCoreAudio * core_audio)
{
  if (core_audio->is_passthrough) {
    _io_proc_spdif_stop (core_audio);
  } else {
    gst_core_audio_io_proc_stop (core_audio);
  }

  return TRUE;
}

static gboolean
gst_core_audio_get_samples_and_latency_impl (GstCoreAudio * core_audio,
    gdouble rate, guint * samples, gdouble * latency)
{
  OSStatus status;
  UInt32 size = sizeof (double);

  if (core_audio->is_passthrough) {
    *samples = _audio_device_get_latency (core_audio->device_id);
    *samples += _audio_stream_get_latency (core_audio->stream_id);
    *latency = (double) *samples / rate;
  } else {
    status = AudioUnitGetProperty (core_audio->audiounit, kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0,        /* N/A for global */
        latency, &size);

    if (status) {
      GST_WARNING_OBJECT (core_audio->osxbuf, "Failed to get latency: %"
          GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
      *samples = 0;
      return FALSE;
    }

    *samples = *latency * rate;
  }
  return TRUE;
}

static gboolean
gst_core_audio_initialize_impl (GstCoreAudio * core_audio,
    AudioStreamBasicDescription format, GstCaps * caps,
    gboolean is_passthrough, guint32 * frame_size)
{
  gboolean ret = FALSE;

  core_audio->is_passthrough = is_passthrough;
  if (is_passthrough) {
    if (!_acquire_spdif (core_audio, format))
      goto done;
    _monitorize_spdif (core_audio);
  } else {
    OSStatus status;
    UInt32 propertySize;

    core_audio->stream_idx = 0;
    if (!gst_core_audio_set_format (core_audio, format))
      goto done;

    if (!gst_core_audio_set_channels_layout (core_audio,
            format.mChannelsPerFrame, caps))
      goto done;

    if (!gst_core_audio_bind_device (core_audio))
      goto done;

    if (core_audio->is_src) {
      propertySize = sizeof (*frame_size);
      status = AudioUnitGetProperty (core_audio->audiounit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, 0,     /* N/A for global */
          frame_size, &propertySize);

      if (status) {
        GST_WARNING_OBJECT (core_audio->osxbuf, "Failed to get frame size: %"
            GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status));
        goto done;
      }
    }
  }

  ret = TRUE;

done:
  if (ret) {
    GST_DEBUG_OBJECT (core_audio, "osxbuf ring buffer acquired");
  }
  return ret;
}

static gboolean
gst_core_audio_select_device_impl (AudioDeviceID * device_id)
{
  AudioDeviceID *devices = NULL;
  AudioDeviceID default_device_id = 0;
  AudioChannelLayout *channel_layout;
  gint i, ndevices = 0;
  gboolean res = FALSE;

  devices = _audio_system_get_devices (&ndevices);

  if (ndevices < 1) {
    GST_ERROR ("no audio output devices found");
    goto done;
  }

  GST_DEBUG ("found %d audio device(s)", ndevices);

  for (i = 0; i < ndevices; i++) {
    gchar *device_name;

    if ((device_name = _audio_device_get_name (devices[i]))) {
      if (!_audio_device_has_output (devices[i])) {
        GST_DEBUG ("Input Device ID: %u Name: %s",
            (unsigned) devices[i], device_name);
      } else {
        GST_DEBUG ("Output Device ID: %u Name: %s",
            (unsigned) devices[i], device_name);

        channel_layout =
            gst_core_audio_audio_device_get_channel_layout (devices[i]);
        if (channel_layout) {
          gst_core_audio_dump_channel_layout (channel_layout);
          g_free (channel_layout);
        }
      }

      g_free (device_name);
    }
  }

  /* Find the ID of the default output device */
  default_device_id = _audio_system_get_default_output ();

  /* Here we decide if selected device is valid or autoselect
   * the default one when required */
  if (*device_id == kAudioDeviceUnknown) {
    if (default_device_id != kAudioDeviceUnknown) {
      *device_id = default_device_id;
      res = TRUE;
    }
  } else {
    for (i = 0; i < ndevices; i++) {
      if (*device_id == devices[i]) {
        res = TRUE;
      }
    }

    if (res && !_audio_device_is_alive (*device_id)) {
      GST_ERROR ("Requested device not usable");
      res = FALSE;
      goto done;
    }
  }

done:
  g_free (devices);
  return res;
}

static gboolean
gst_core_audio_audio_device_is_spdif_avail_impl (AudioDeviceID device_id)
{
  AudioStreamID *streams = NULL;
  gint i, nstreams = 0;
  gboolean res = FALSE;

  streams = _audio_device_get_streams (device_id, &nstreams);
  GST_DEBUG ("found %d streams", nstreams);
  if (streams) {
    for (i = 0; i < nstreams; i++) {
      if (_audio_stream_is_spdif_avail (streams[i])) {
        res = TRUE;
      }
    }

    g_free (streams);
  }

  return res;
}

static gboolean
gst_core_audio_select_source_device_impl (AudioDeviceID * device_id)
{
  OSStatus status;
  UInt32 propertySize;

  if (*device_id == kAudioDeviceUnknown) {
    /* If no specific device has been selected by the user, then pick the
     * default device */
    GST_DEBUG ("Selecting device for OSXAudioSrc");
    propertySize = sizeof (*device_id);
    status = AudioHardwareGetProperty (kAudioHardwarePropertyDefaultInputDevice,
        &propertySize, device_id);

    if (status) {
      GST_WARNING ("AudioHardwareGetProperty returned %d", (int) status);
    } else {
      GST_DEBUG ("AudioHardwareGetProperty returned 0");
    }

    if (*device_id == kAudioDeviceUnknown) {
      GST_WARNING ("AudioHardwareGetProperty: device_id is "
          "kAudioDeviceUnknown");
    }

    GST_DEBUG ("AudioHardwareGetProperty: device_id is %lu", (long) *device_id);
  }

  return TRUE;
}
