/*
 * 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;
    }
  }

beach:
  gst_core_audio_dump_channel_layout (layout);
  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;
}
