/* GStreamer
 * Copyright (C) 2012 Fluendo S.A. <support@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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <string.h>

#include "opensles.h"
#include "openslesringbuffer.h"

GST_DEBUG_CATEGORY_STATIC (opensles_ringbuffer_debug);
#define GST_CAT_DEFAULT opensles_ringbuffer_debug

#define _do_init \
  GST_DEBUG_CATEGORY_INIT (opensles_ringbuffer_debug, \
      "opensles_ringbuffer", 0, "OpenSL ES ringbuffer");

#define parent_class gst_opensles_ringbuffer_parent_class
G_DEFINE_TYPE_WITH_CODE (GstOpenSLESRingBuffer, gst_opensles_ringbuffer,
    GST_TYPE_AUDIO_RING_BUFFER, _do_init);

/*
 * Some generic helper functions
 */

static inline SLuint32
_opensles_sample_rate (guint rate)
{
  switch (rate) {
    case 8000:
      return SL_SAMPLINGRATE_8;
    case 11025:
      return SL_SAMPLINGRATE_11_025;
    case 12000:
      return SL_SAMPLINGRATE_12;
    case 16000:
      return SL_SAMPLINGRATE_16;
    case 22050:
      return SL_SAMPLINGRATE_22_05;
    case 24000:
      return SL_SAMPLINGRATE_24;
    case 32000:
      return SL_SAMPLINGRATE_32;
    case 44100:
      return SL_SAMPLINGRATE_44_1;
    case 48000:
      return SL_SAMPLINGRATE_48;
    case 64000:
      return SL_SAMPLINGRATE_64;
    case 88200:
      return SL_SAMPLINGRATE_88_2;
    case 96000:
      return SL_SAMPLINGRATE_96;
    case 192000:
      return SL_SAMPLINGRATE_192;
    default:
      return 0;
  }
}

static inline SLuint32
_opensles_channel_mask (GstAudioRingBufferSpec * spec)
{
  switch (spec->info.channels) {
    case 1:
      return (SL_SPEAKER_FRONT_CENTER);
    case 2:
      return (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
    default:
      return 0;
  }
}

static inline void
_opensles_format (GstAudioRingBufferSpec * spec, SLDataFormat_PCM * format)
{
  format->formatType = SL_DATAFORMAT_PCM;
  format->numChannels = spec->info.channels;
  format->samplesPerSec = _opensles_sample_rate (spec->info.rate);
  format->bitsPerSample = spec->info.finfo->depth;
  format->containerSize = spec->info.finfo->width;
  format->channelMask = _opensles_channel_mask (spec);
  format->endianness =
      ((spec->info.finfo->endianness ==
          G_BIG_ENDIAN) ? SL_BYTEORDER_BIGENDIAN : SL_BYTEORDER_LITTLEENDIAN);
}

/* 
 * Recorder related functions
 */

static gboolean
_opensles_recorder_acquire (GstAudioRingBuffer * rb,
    GstAudioRingBufferSpec * spec)
{
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;
  SLDataFormat_PCM format;

  /* Configure audio source */
  SLDataLocator_IODevice loc_dev = {
    SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
    SL_DEFAULTDEVICEID_AUDIOINPUT, NULL
  };
  SLDataSource audioSrc = { &loc_dev, NULL };

  /* Configure audio sink */
  SLDataLocator_AndroidSimpleBufferQueue loc_bq = {
    SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2
  };
  SLDataSink audioSink = { &loc_bq, &format };

  /* Required optional interfaces */
  const SLInterfaceID id[1] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
  const SLboolean req[1] = { SL_BOOLEAN_TRUE };

  /* Define the audio format in OpenSL ES terminology */
  _opensles_format (spec, &format);

  /* Create the audio recorder object (requires the RECORD_AUDIO permission) */
  result = (*thiz->engineEngine)->CreateAudioRecorder (thiz->engineEngine,
      &thiz->recorderObject, &audioSrc, &audioSink, 1, id, req);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "engine.CreateAudioRecorder failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Realize the audio recorder object */
  result =
      (*thiz->recorderObject)->Realize (thiz->recorderObject, SL_BOOLEAN_FALSE);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "recorder.Realize failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Get the record interface */
  result = (*thiz->recorderObject)->GetInterface (thiz->recorderObject,
      SL_IID_RECORD, &thiz->recorderRecord);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "recorder.GetInterface(Record) failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Get the buffer queue interface */
  result =
      (*thiz->recorderObject)->GetInterface (thiz->recorderObject,
      SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &thiz->bufferQueue);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "recorder.GetInterface(BufferQueue) failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  return TRUE;

failed:
  return FALSE;
}

/* This callback function is executed when the ringbuffer is started to preroll
 * the output buffer queue with empty buffers, from app thread, and each time
 * there's a filled buffer, from audio device processing thread,
 * the callback behaviour.
 */
static void
_opensles_recorder_cb (SLAndroidSimpleBufferQueueItf bufferQueue, void *context)
{
  GstAudioRingBuffer *rb = GST_AUDIO_RING_BUFFER_CAST (context);
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;
  guint8 *ptr;
  gint seg;
  gint len;

  /* Advance only when we are called by the callback function */
  if (bufferQueue) {
    gst_audio_ring_buffer_advance (rb, 1);
  }

  /* Get a segment form the GStreamer ringbuffer to write in */
  if (!gst_audio_ring_buffer_prepare_read (rb, &seg, &ptr, &len)) {
    GST_WARNING_OBJECT (rb, "No segment available");
    return;
  }

  GST_LOG_OBJECT (thiz, "enqueue: %p size %d segment: %d", ptr, len, seg);

  /* Enqueue the sefment as buffer to be written */
  result = (*thiz->bufferQueue)->Enqueue (thiz->bufferQueue, ptr, len);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "bufferQueue.Enqueue failed(0x%08x)",
        (guint32) result);
    return;
  }
}

static gboolean
_opensles_recorder_start (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;

  /* Register callback on the buffer queue */
  if (!thiz->is_queue_callback_registered) {
    result = (*thiz->bufferQueue)->RegisterCallback (thiz->bufferQueue,
        _opensles_recorder_cb, rb);
    if (result != SL_RESULT_SUCCESS) {
      GST_ERROR_OBJECT (thiz, "bufferQueue.RegisterCallback failed(0x%08x)",
          (guint32) result);
      return FALSE;
    }
    thiz->is_queue_callback_registered = TRUE;
  }

  /* Preroll one buffer */
  _opensles_recorder_cb (NULL, rb);

  /* Start recording */
  result =
      (*thiz->recorderRecord)->SetRecordState (thiz->recorderRecord,
      SL_RECORDSTATE_RECORDING);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "recorder.SetRecordState failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }

  return TRUE;
}

static gboolean
_opensles_recorder_stop (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;

  /* Stop recording */
  result =
      (*thiz->recorderRecord)->SetRecordState (thiz->recorderRecord,
      SL_RECORDSTATE_STOPPED);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "recorder.SetRecordState failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }

  /* Unregister callback on the buffer queue */
  result = (*thiz->bufferQueue)->RegisterCallback (thiz->bufferQueue,
      NULL, NULL);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "bufferQueue.RegisterCallback failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }
  thiz->is_queue_callback_registered = FALSE;

  /* Reset the queue */
  result = (*thiz->bufferQueue)->Clear (thiz->bufferQueue);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "bufferQueue.Clear failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }

  return TRUE;
}

/*
 * Player related functions
 */

static gboolean
_opensles_player_change_volume (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;
  SLresult result;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  if (thiz->playerVolume) {
    gint millibel = (1.0 - thiz->volume) * -5000.0;
    result =
        (*thiz->playerVolume)->SetVolumeLevel (thiz->playerVolume, millibel);
    if (result != SL_RESULT_SUCCESS) {
      GST_ERROR_OBJECT (thiz, "player.SetVolumeLevel failed(0x%08x)",
          (guint32) result);
      return FALSE;
    }
    GST_DEBUG_OBJECT (thiz, "changed volume to %d", millibel);
  }

  return TRUE;
}

static gboolean
_opensles_player_change_mute (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;
  SLresult result;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  if (thiz->playerVolume) {
    result = (*thiz->playerVolume)->SetMute (thiz->playerVolume, thiz->mute);
    if (result != SL_RESULT_SUCCESS) {
      GST_ERROR_OBJECT (thiz, "player.SetMute failed(0x%08x)",
          (guint32) result);
      return FALSE;
    }
    GST_DEBUG_OBJECT (thiz, "changed mute to %d", thiz->mute);
  }

  return TRUE;
}

/* This is a callback function invoked by the playback device thread and
 * it's used to monitor position changes */
static void
_opensles_player_event_cb (SLPlayItf caller, void *context, SLuint32 event)
{
  if (event & SL_PLAYEVENT_HEADATNEWPOS) {
    SLmillisecond position;

    (*caller)->GetPosition (caller, &position);
    GST_LOG_OBJECT (context, "at position=%u ms", (guint) position);
  }
}

static gboolean
_opensles_player_acquire (GstAudioRingBuffer * rb,
    GstAudioRingBufferSpec * spec)
{
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;
  SLDataFormat_PCM format;

  /* Configure audio source */
  SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
    SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
    MIN (32, (spec->segtotal >> 1))
  };
  SLDataSource audioSrc = { &loc_bufq, &format };

  /* Configure audio sink */
  SLDataLocator_OutputMix loc_outmix = {
    SL_DATALOCATOR_OUTPUTMIX, thiz->outputMixObject
  };
  SLDataSink audioSink = { &loc_outmix, NULL };

  /* Define the required interfaces */
  const SLInterfaceID ids[2] = { SL_IID_BUFFERQUEUE, SL_IID_VOLUME };
  const SLboolean req[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };

  /* Define the format in OpenSL ES terminology */
  _opensles_format (spec, &format);

  /* Create the player object */
  result = (*thiz->engineEngine)->CreateAudioPlayer (thiz->engineEngine,
      &thiz->playerObject, &audioSrc, &audioSink, 2, ids, req);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "engine.CreateAudioPlayer failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Realize the player object */
  result =
      (*thiz->playerObject)->Realize (thiz->playerObject, SL_BOOLEAN_FALSE);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.Realize failed(0x%08x)", (guint32) result);
    goto failed;
  }

  /* Get the play interface */
  result = (*thiz->playerObject)->GetInterface (thiz->playerObject,
      SL_IID_PLAY, &thiz->playerPlay);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.GetInterface(Play) failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Get the buffer queue interface */
  result = (*thiz->playerObject)->GetInterface (thiz->playerObject,
      SL_IID_BUFFERQUEUE, &thiz->bufferQueue);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.GetInterface(BufferQueue) failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Get the volume interface */
  result = (*thiz->playerObject)->GetInterface (thiz->playerObject,
      SL_IID_VOLUME, &thiz->playerVolume);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.GetInterface(Volume) failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Request position update events at each 20 ms */
  result = (*thiz->playerPlay)->SetPositionUpdatePeriod (thiz->playerPlay, 20);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.SetPositionUpdatePeriod failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Define the event mask to be monitorized */
  result = (*thiz->playerPlay)->SetCallbackEventsMask (thiz->playerPlay,
      SL_PLAYEVENT_HEADATNEWPOS);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.SetCallbackEventsMask failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Register a callback to process the events */
  result = (*thiz->playerPlay)->RegisterCallback (thiz->playerPlay,
      _opensles_player_event_cb, thiz);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.RegisterCallback(event_cb) failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  /* Configure the volume and mute state */
  _opensles_player_change_volume (rb);
  _opensles_player_change_mute (rb);

  /* Allocate the queue associated ringbuffer memory */
  thiz->data_segtotal = loc_bufq.numBuffers;
  thiz->data_size = spec->segsize * thiz->data_segtotal;
  thiz->data = g_malloc0 (thiz->data_size);
  g_atomic_int_set (&thiz->segqueued, 0);
  g_atomic_int_set (&thiz->is_prerolled, 0);
  thiz->cursor = 0;

  return TRUE;

failed:
  return FALSE;
}

/* This callback function is executed when the ringbuffer is started to preroll
 * the input buffer queue with few buffers, from app thread, and each time
 * that rendering of one buffer finishes, from audio device processing thread,
 * the callback behaviour.
 *
 * We wrap the queue behaviour with an appropriate chunk of memory (queue len *
 * ringbuffer segment size) which is used to hold the audio data while it's 
 * being processed in the queue. The memory region is used whit a ringbuffer
 * behaviour.
 */
static void
_opensles_player_cb (SLAndroidSimpleBufferQueueItf bufferQueue, void *context)
{
  GstAudioRingBuffer *rb = GST_AUDIO_RING_BUFFER_CAST (context);
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;
  guint8 *ptr, *cur;
  gint seg;
  gint len;

  /* Get a segment form the GStreamer ringbuffer to read some samples */
  if (!gst_audio_ring_buffer_prepare_read (rb, &seg, &ptr, &len)) {
    GST_WARNING_OBJECT (rb, "No segment available");
    return;
  }

  /* copy the segment data to our queue associated ringbuffer memory */
  cur = thiz->data + (thiz->cursor * rb->spec.segsize);
  memcpy (cur, ptr, len);
  g_atomic_int_inc (&thiz->segqueued);

  GST_LOG_OBJECT (thiz, "enqueue: %p size %d segment: %d in queue[%d]",
      cur, len, seg, thiz->cursor);
  /* advance the cursor in our queue associated ringbuffer */
  thiz->cursor = (thiz->cursor + 1) % thiz->data_segtotal;

  /* Enqueue the buffer to be rendered */
  result = (*thiz->bufferQueue)->Enqueue (thiz->bufferQueue, cur, len);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "bufferQueue.Enqueue failed(0x%08x)",
        (guint32) result);
    return;
  }

  /* Fill with silence samples the segment of the GStreamer ringbuffer */
  gst_audio_ring_buffer_clear (rb, seg);
  /* Make the segment reusable */
  gst_audio_ring_buffer_advance (rb, 1);
}

static gboolean
_opensles_player_start (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;
  gint i;

  /* Register callback on the buffer queue */
  if (!thiz->is_queue_callback_registered) {
    result = (*thiz->bufferQueue)->RegisterCallback (thiz->bufferQueue,
        _opensles_player_cb, rb);
    if (result != SL_RESULT_SUCCESS) {
      GST_ERROR_OBJECT (thiz, "bufferQueue.RegisterCallback failed(0x%08x)",
          (guint32) result);
      return FALSE;
    }
    thiz->is_queue_callback_registered = TRUE;
  }

  /* Fill the queue by enqueing buffers */
  if (!g_atomic_int_get (&thiz->is_prerolled)) {
    for (i = 0; i < thiz->data_segtotal; i++) {
      _opensles_player_cb (NULL, rb);
    }
    g_atomic_int_set (&thiz->is_prerolled, 1);
  }

  /* Change player state into PLAYING */
  result =
      (*thiz->playerPlay)->SetPlayState (thiz->playerPlay,
      SL_PLAYSTATE_PLAYING);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.SetPlayState failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }

  return TRUE;
}

static gboolean
_opensles_player_pause (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;

  result =
      (*thiz->playerPlay)->SetPlayState (thiz->playerPlay, SL_PLAYSTATE_PAUSED);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.SetPlayState failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }

  return TRUE;
}

static gboolean
_opensles_player_stop (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  SLresult result;

  /* Change player state into STOPPED */
  result =
      (*thiz->playerPlay)->SetPlayState (thiz->playerPlay,
      SL_PLAYSTATE_STOPPED);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "player.SetPlayState failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }

  /* Unregister callback on the buffer queue */
  result = (*thiz->bufferQueue)->RegisterCallback (thiz->bufferQueue,
      NULL, NULL);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "bufferQueue.RegisterCallback failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }
  thiz->is_queue_callback_registered = FALSE;

  /* Reset the queue */
  result = (*thiz->bufferQueue)->Clear (thiz->bufferQueue);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "bufferQueue.Clear failed(0x%08x)",
        (guint32) result);
    return FALSE;
  }

  /* Reset our state */
  g_atomic_int_set (&thiz->segqueued, 0);
  thiz->cursor = 0;

  return TRUE;
}

/*
 * OpenSL ES ringbuffer wrapper
 */

GstAudioRingBuffer *
gst_opensles_ringbuffer_new (RingBufferMode mode)
{
  GstOpenSLESRingBuffer *thiz;

  g_return_val_if_fail (mode > RB_MODE_NONE && mode < RB_MODE_LAST, NULL);

  thiz = g_object_new (GST_TYPE_OPENSLES_RING_BUFFER, NULL);

  if (thiz) {
    thiz->mode = mode;
    if (mode == RB_MODE_SRC) {
      thiz->acquire = _opensles_recorder_acquire;
      thiz->start = _opensles_recorder_start;
      thiz->pause = _opensles_recorder_stop;
      thiz->stop = _opensles_recorder_stop;
      thiz->change_volume = NULL;
    } else if (mode == RB_MODE_SINK_PCM) {
      thiz->acquire = _opensles_player_acquire;
      thiz->start = _opensles_player_start;
      thiz->pause = _opensles_player_pause;
      thiz->stop = _opensles_player_stop;
      thiz->change_volume = _opensles_player_change_volume;
    }
  }

  GST_DEBUG_OBJECT (thiz, "ringbuffer created");

  return GST_AUDIO_RING_BUFFER (thiz);
}

void
gst_opensles_ringbuffer_set_volume (GstAudioRingBuffer * rb, gfloat volume)
{
  GstOpenSLESRingBuffer *thiz;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  thiz->volume = volume;

  if (thiz->change_volume) {
    thiz->change_volume (rb);
  }
}

void
gst_opensles_ringbuffer_set_mute (GstAudioRingBuffer * rb, gboolean mute)
{
  GstOpenSLESRingBuffer *thiz;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  thiz->mute = mute;

  if (thiz->change_mute) {
    thiz->change_mute (rb);
  }
}

static gboolean
gst_opensles_ringbuffer_open_device (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;
  SLresult result;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  /* Create and realize the engine object */
  thiz->engineObject = gst_opensles_get_engine ();
  if (!thiz->engineObject) {
    GST_ERROR_OBJECT (thiz, "Failed to get engine object");
    goto failed;
  }

  /* Get the engine interface, which is needed in order to create other objects */
  result = (*thiz->engineObject)->GetInterface (thiz->engineObject,
      SL_IID_ENGINE, &thiz->engineEngine);
  if (result != SL_RESULT_SUCCESS) {
    GST_ERROR_OBJECT (thiz, "engine.GetInterface(Engine) failed(0x%08x)",
        (guint32) result);
    goto failed;
  }

  if (thiz->mode == RB_MODE_SINK_PCM) {
    SLOutputMixItf outputMix;

    /* Create an output mixer object */
    result = (*thiz->engineEngine)->CreateOutputMix (thiz->engineEngine,
        &thiz->outputMixObject, 0, NULL, NULL);
    if (result != SL_RESULT_SUCCESS) {
      GST_ERROR_OBJECT (thiz, "engine.CreateOutputMix failed(0x%08x)",
          (guint32) result);
      goto failed;
    }

    /* Realize the output mixer object */
    result = (*thiz->outputMixObject)->Realize (thiz->outputMixObject,
        SL_BOOLEAN_FALSE);
    if (result != SL_RESULT_SUCCESS) {
      GST_ERROR_OBJECT (thiz, "outputMix.Realize failed(0x%08x)",
          (guint32) result);
      goto failed;
    }

    /* Get the mixer interface */
    result = (*thiz->outputMixObject)->GetInterface (thiz->outputMixObject,
        SL_IID_OUTPUTMIX, &outputMix);
    if (result != SL_RESULT_SUCCESS) {
      GST_WARNING_OBJECT (thiz, "outputMix.GetInterface failed(0x%08x)",
          (guint32) result);
    } else {
      SLint32 numDevices = MAX_NUMBER_OUTPUT_DEVICES;
      SLuint32 deviceIDs[MAX_NUMBER_OUTPUT_DEVICES];
      gint i;

      /* Query the list of output devices */
      (*outputMix)->GetDestinationOutputDeviceIDs (outputMix, &numDevices,
          deviceIDs);
      GST_DEBUG_OBJECT (thiz, "Found %d output devices", (gint) numDevices);
      for (i = 0; i < numDevices; i++) {
        GST_DEBUG_OBJECT (thiz, "  DeviceID: %08x", (guint) deviceIDs[i]);
      }
    }
  }

  GST_DEBUG_OBJECT (thiz, "device opened");
  return TRUE;

failed:
  return FALSE;
}

static gboolean
gst_opensles_ringbuffer_close_device (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  /* Destroy the output mix object */
  if (thiz->outputMixObject) {
    (*thiz->outputMixObject)->Destroy (thiz->outputMixObject);
    thiz->outputMixObject = NULL;
  }

  /* Destroy the engine object and invalidate all associated interfaces */
  if (thiz->engineObject) {
    gst_opensles_release_engine (thiz->engineObject);
    thiz->engineObject = NULL;
    thiz->engineEngine = NULL;
  }

  thiz->bufferQueue = NULL;

  GST_DEBUG_OBJECT (thiz, "device closed");
  return TRUE;
}

static gboolean
gst_opensles_ringbuffer_acquire (GstAudioRingBuffer * rb,
    GstAudioRingBufferSpec * spec)
{
  GstOpenSLESRingBuffer *thiz;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  /* Instantiate and configure the OpenSL ES interfaces */
  if (!thiz->acquire (rb, spec)) {
    return FALSE;
  }

  /* Initialize our ringbuffer memory region */
  rb->size = spec->segtotal * spec->segsize;
  rb->memory = g_malloc0 (rb->size);

  GST_DEBUG_OBJECT (thiz, "ringbuffer acquired");
  return TRUE;
}

static gboolean
gst_opensles_ringbuffer_release (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;

  thiz = GST_OPENSLES_RING_BUFFER (rb);

  /* XXX: We need to sleep a bit before destroying the player object
   * because of a bug in Android in versions < 4.2.
   *
   * OpenSLES is using AudioTrack for rendering the sound. AudioTrack
   * has a thread that pulls raw audio from the buffer queue and then
   * passes it forward to AudioFlinger (AudioTrack::processAudioBuffer()).
   * This thread is calling various callbacks on events, e.g. when
   * an underrun happens or to request data. OpenSLES sets this callback
   * on AudioTrack (audioTrack_callBack_pullFromBuffQueue() from
   * android_AudioPlayer.cpp). Among other things this is taking a lock
   * on the player interface.
   *
   * Now if we destroy the player interface object, it will first of all
   * take the player interface lock (IObject_Destroy()). Then it destroys
   * the audio player instance (android_audioPlayer_destroy()) which then
   * calls stop() on the AudioTrack and deletes it. Now the destructor of
   * AudioTrack will wait until the rendering thread (AudioTrack::processAudioBuffer())
   * has finished.
   *
   * If all this happens with bad timing it can happen that the rendering
   * thread is currently e.g. handling underrun but did not lock the player
   * interface object yet. Then destroying happens and takes the lock and waits
   * for the thread to finish. Then the thread tries to take the lock and waits
   * forever.
   *
   * We wait a bit before destroying the player object to make sure that
   * the rendering thread finished whatever it was doing, and then stops
   * (note: we called gst_opensles_ringbuffer_stop() before this already).
   */

  /* Destroy audio player object, and invalidate all associated interfaces */
  if (thiz->playerObject) {
    g_usleep (50000);
    (*thiz->playerObject)->Destroy (thiz->playerObject);
    thiz->playerObject = NULL;
    thiz->playerPlay = NULL;
    thiz->playerVolume = NULL;
  }

  /* Destroy audio recorder object, and invalidate all associated interfaces */
  if (thiz->recorderObject) {
    g_usleep (50000);
    (*thiz->recorderObject)->Destroy (thiz->recorderObject);
    thiz->recorderObject = NULL;
    thiz->recorderRecord = NULL;
  }

  if (thiz->data) {
    g_free (thiz->data);
    thiz->data = NULL;
  }

  if (rb->memory) {
    g_free (rb->memory);
    rb->memory = NULL;
    rb->size = 0;
  }

  GST_DEBUG_OBJECT (thiz, "ringbuffer released");
  return TRUE;
}

static gboolean
gst_opensles_ringbuffer_start (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;
  gboolean res;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  res = thiz->start (rb);

  GST_DEBUG_OBJECT (thiz, "ringbuffer %s started", (res ? "" : "not"));
  return res;
}

static gboolean
gst_opensles_ringbuffer_pause (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;
  gboolean res;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  res = thiz->pause (rb);

  GST_DEBUG_OBJECT (thiz, "ringbuffer %s paused", (res ? "" : "not"));
  return res;
}

static gboolean
gst_opensles_ringbuffer_stop (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;
  gboolean res;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
  res = thiz->stop (rb);

  GST_DEBUG_OBJECT (thiz, "ringbuffer %s stopped", (res ? " " : "not"));
  return res;
}

static guint
gst_opensles_ringbuffer_delay (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;
  guint res = 0;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  if (thiz->playerPlay) {
    SLuint32 state;
    SLmillisecond position;
    guint64 playedpos = 0, queuedpos = 0;
    (*thiz->playerPlay)->GetPlayState (thiz->playerPlay, &state);
    if (state == SL_PLAYSTATE_PLAYING) {
      (*thiz->playerPlay)->GetPosition (thiz->playerPlay, &position);
      playedpos =
          gst_util_uint64_scale_round (position, rb->spec.info.rate, 1000);
      queuedpos = g_atomic_int_get (&thiz->segqueued) * rb->samples_per_seg;
      res = queuedpos - playedpos;
    }

    GST_LOG_OBJECT (thiz, "queued samples %" G_GUINT64_FORMAT " position %u ms "
        "(%" G_GUINT64_FORMAT " samples) delay %u samples",
        queuedpos, (guint) position, playedpos, res);
  }

  return res;
}

static void
gst_opensles_ringbuffer_clear_all (GstAudioRingBuffer * rb)
{
  GstOpenSLESRingBuffer *thiz;

  thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);

  if (thiz->data) {
    SLresult result;

    memset (thiz->data, 0, thiz->data_size);
    g_atomic_int_set (&thiz->segqueued, 0);
    thiz->cursor = 0;
    /* Reset the queue */
    result = (*thiz->bufferQueue)->Clear (thiz->bufferQueue);
    if (result != SL_RESULT_SUCCESS) {
      GST_WARNING_OBJECT (thiz, "bufferQueue.Clear failed(0x%08x)",
          (guint32) result);
    }
    g_atomic_int_set (&thiz->is_prerolled, 0);
  }

  GST_CALL_PARENT (GST_AUDIO_RING_BUFFER_CLASS, clear_all, (rb));
}

static void
gst_opensles_ringbuffer_dispose (GObject * object)
{
  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gst_opensles_ringbuffer_finalize (GObject * object)
{
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_opensles_ringbuffer_class_init (GstOpenSLESRingBufferClass * klass)
{
  GObjectClass *gobject_class;
  GstAudioRingBufferClass *gstringbuffer_class;

  gobject_class = (GObjectClass *) klass;
  gstringbuffer_class = (GstAudioRingBufferClass *) klass;

  gobject_class->dispose = gst_opensles_ringbuffer_dispose;
  gobject_class->finalize = gst_opensles_ringbuffer_finalize;

  gstringbuffer_class->open_device =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_open_device);
  gstringbuffer_class->close_device =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_close_device);
  gstringbuffer_class->acquire =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_acquire);
  gstringbuffer_class->release =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_release);
  gstringbuffer_class->start =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_start);
  gstringbuffer_class->pause =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_pause);
  gstringbuffer_class->resume =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_start);
  gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_stop);
  gstringbuffer_class->delay =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_delay);
  gstringbuffer_class->clear_all =
      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_clear_all);
}

static void
gst_opensles_ringbuffer_init (GstOpenSLESRingBuffer * thiz)
{
  thiz->mode = RB_MODE_NONE;
  thiz->engineObject = NULL;
  thiz->outputMixObject = NULL;
  thiz->playerObject = NULL;
  thiz->recorderObject = NULL;
  thiz->is_queue_callback_registered = FALSE;
}
