/* 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
   * 4 buffers is the "typical" size as optimized inside Android's
   * OpenSL ES, see frameworks/wilhelm/src/itfstruct.h BUFFER_HEADER_TYPICAL
   *
   * Also only use half of our segment size to make sure that there's always
   * some more queued up in our ringbuffer and we don't start to read silence.
   */
  SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
    SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, MIN (4, MAX (spec->segtotal >> 1,
            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;

  /* 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 a buffer */
  if (!g_atomic_int_get (&thiz->is_prerolled)) {
    _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;
}
