/* GStreamer
 * Copyright (C) 2013 Alessandro Decina <alessandro.d@gmail.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 Street, Suite 500,
 * Boston, MA 02110-1335, USA.
 */
/**
 * SECTION:element-atdec
 * @title: atdec
 *
 * AudioToolbox based decoder.
 *
 * ## Example launch line
 * |[
 * gst-launch-1.0 -v filesrc location=file.mov ! qtdemux ! queue ! aacparse ! atdec ! autoaudiosink
 * ]|
 * Decode aac audio from a mov file
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>
#include <gst/audio/gstaudiodecoder.h>
#include "atdec.h"

GST_DEBUG_CATEGORY_STATIC (gst_atdec_debug_category);
#define GST_CAT_DEFAULT gst_atdec_debug_category

static void gst_atdec_set_property (GObject * object,
    guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_atdec_get_property (GObject * object,
    guint property_id, GValue * value, GParamSpec * pspec);
static void gst_atdec_finalize (GObject * object);

static gboolean gst_atdec_start (GstAudioDecoder * decoder);
static gboolean gst_atdec_stop (GstAudioDecoder * decoder);
static gboolean gst_atdec_set_format (GstAudioDecoder * decoder,
    GstCaps * caps);
static GstFlowReturn gst_atdec_handle_frame (GstAudioDecoder * decoder,
    GstBuffer * buffer);
static void gst_atdec_flush (GstAudioDecoder * decoder, gboolean hard);
static void gst_atdec_buffer_emptied (void *user_data,
    AudioQueueRef queue, AudioQueueBufferRef buffer);

enum
{
  PROP_0
};

static GstStaticPadTemplate gst_atdec_src_template =
    GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE ("S16LE") ", layout=interleaved;"
        GST_AUDIO_CAPS_MAKE ("F32LE") ", layout=interleaved")
    );

static GstStaticPadTemplate gst_atdec_sink_template =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/mpeg, mpegversion=4, framed=true, channels=[1,max];"
        "audio/mpeg, mpegversion=1, layer=[1, 3]")
    );

G_DEFINE_TYPE_WITH_CODE (GstATDec, gst_atdec, GST_TYPE_AUDIO_DECODER,
    GST_DEBUG_CATEGORY_INIT (gst_atdec_debug_category, "atdec", 0,
        "debug category for atdec element"));

static GstStaticCaps aac_caps = GST_STATIC_CAPS ("audio/mpeg, mpegversion=4");
static GstStaticCaps mp3_caps =
GST_STATIC_CAPS ("audio/mpeg, mpegversion=1, layer=[1, 3]");
static GstStaticCaps raw_caps = GST_STATIC_CAPS ("audio/x-raw");

static void
gst_atdec_class_init (GstATDecClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstAudioDecoderClass *audio_decoder_class = GST_AUDIO_DECODER_CLASS (klass);

  gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
      &gst_atdec_src_template);
  gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
      &gst_atdec_sink_template);

  gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
      "AudioToolbox based audio decoder",
      "Codec/Decoder/Audio",
      "AudioToolbox based audio decoder",
      "Alessandro Decina <alessandro.d@gmail.com>");

  gobject_class->set_property = gst_atdec_set_property;
  gobject_class->get_property = gst_atdec_get_property;
  gobject_class->finalize = gst_atdec_finalize;
  audio_decoder_class->start = GST_DEBUG_FUNCPTR (gst_atdec_start);
  audio_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_atdec_stop);
  audio_decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_atdec_set_format);
  audio_decoder_class->handle_frame =
      GST_DEBUG_FUNCPTR (gst_atdec_handle_frame);
  audio_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_atdec_flush);
}

static void
gst_atdec_init (GstATDec * atdec)
{
  gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (atdec), TRUE);
  atdec->queue = NULL;
}

void
gst_atdec_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GstATDec *atdec = GST_ATDEC (object);

  GST_DEBUG_OBJECT (atdec, "set_property");

  switch (property_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_atdec_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GstATDec *atdec = GST_ATDEC (object);

  GST_DEBUG_OBJECT (atdec, "get_property");

  switch (property_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static void
gst_atdec_destroy_queue (GstATDec * atdec, gboolean drain)
{
  AudioQueueStop (atdec->queue, drain);
  AudioQueueDispose (atdec->queue, true);
  atdec->queue = NULL;
  atdec->output_position = 0;
  atdec->input_position = 0;
}

void
gst_atdec_finalize (GObject * object)
{
  GstATDec *atdec = GST_ATDEC (object);

  GST_DEBUG_OBJECT (atdec, "finalize");

  if (atdec->queue)
    gst_atdec_destroy_queue (atdec, FALSE);

  G_OBJECT_CLASS (gst_atdec_parent_class)->finalize (object);
}

static gboolean
gst_atdec_start (GstAudioDecoder * decoder)
{
  GstATDec *atdec = GST_ATDEC (decoder);

  GST_DEBUG_OBJECT (atdec, "start");
  atdec->output_position = 0;
  atdec->input_position = 0;

  return TRUE;
}

static gboolean
gst_atdec_stop (GstAudioDecoder * decoder)
{
  GstATDec *atdec = GST_ATDEC (decoder);

  gst_atdec_destroy_queue (atdec, FALSE);

  return TRUE;
}

static gboolean
can_intersect_static_caps (GstCaps * caps, GstStaticCaps * caps1)
{
  GstCaps *tmp;
  gboolean ret;

  tmp = gst_static_caps_get (caps1);
  ret = gst_caps_can_intersect (caps, tmp);
  gst_caps_unref (tmp);

  return ret;
}

static gboolean
gst_caps_to_at_format (GstCaps * caps, AudioStreamBasicDescription * format)
{
  int channels = 0;
  int rate = 0;
  GstStructure *structure;

  memset (format, 0, sizeof (AudioStreamBasicDescription));

  structure = gst_caps_get_structure (caps, 0);
  gst_structure_get_int (structure, "rate", &rate);
  gst_structure_get_int (structure, "channels", &channels);
  format->mSampleRate = rate;
  format->mChannelsPerFrame = channels;

  if (can_intersect_static_caps (caps, &aac_caps)) {
    format->mFormatID = kAudioFormatMPEG4AAC;
    format->mFramesPerPacket = 1024;
  } else if (can_intersect_static_caps (caps, &mp3_caps)) {
    gint layer, mpegaudioversion = 1;

    gst_structure_get_int (structure, "layer", &layer);
    gst_structure_get_int (structure, "mpegaudioversion", &mpegaudioversion);
    switch (layer) {
      case 1:
        format->mFormatID = kAudioFormatMPEGLayer1;
        format->mFramesPerPacket = 384;
        break;
      case 2:
        format->mFormatID = kAudioFormatMPEGLayer2;
        format->mFramesPerPacket = 1152;
        break;
      case 3:
        format->mFormatID = kAudioFormatMPEGLayer3;
        format->mFramesPerPacket = (mpegaudioversion == 1 ? 1152 : 576);
        break;
      default:
        g_warn_if_reached ();
        format->mFormatID = kAudioFormatMPEGLayer3;
        format->mFramesPerPacket = 1152;
        break;
    }
  } else if (can_intersect_static_caps (caps, &raw_caps)) {
    GstAudioFormat audio_format;
    const char *audio_format_str;

    format->mFormatID = kAudioFormatLinearPCM;
    format->mFramesPerPacket = 1;

    audio_format_str = gst_structure_get_string (structure, "format");
    if (!audio_format_str)
      audio_format_str = "S16LE";

    audio_format = gst_audio_format_from_string (audio_format_str);
    switch (audio_format) {
      case GST_AUDIO_FORMAT_S16LE:
        format->mFormatFlags =
            kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger;
        format->mBitsPerChannel = 16;
        format->mBytesPerPacket = format->mBytesPerFrame = 2 * channels;
        break;
      case GST_AUDIO_FORMAT_F32LE:
        format->mFormatFlags =
            kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsFloat;
        format->mBitsPerChannel = 32;
        format->mBytesPerPacket = format->mBytesPerFrame = 4 * channels;
        break;
      default:
        g_warn_if_reached ();
        break;
    }
  }

  return TRUE;
}

static gboolean
gst_atdec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
{
  OSStatus status;
  AudioStreamBasicDescription input_format = { 0 };
  AudioStreamBasicDescription output_format = { 0 };
  GstAudioInfo output_info = { 0 };
  AudioChannelLayout output_layout = { 0 };
  GstCaps *output_caps;
  AudioTimeStamp timestamp = { 0 };
  AudioQueueBufferRef output_buffer;
  GstATDec *atdec = GST_ATDEC (decoder);

  GST_DEBUG_OBJECT (atdec, "set_format");

  if (atdec->queue)
    gst_atdec_destroy_queue (atdec, TRUE);

  /* configure input_format from caps */
  gst_caps_to_at_format (caps, &input_format);
  /* Remember the number of samples per frame */
  atdec->spf = input_format.mFramesPerPacket;

  /* negotiate output caps */
  output_caps = gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (atdec));
  if (!output_caps)
    output_caps =
        gst_pad_get_pad_template_caps (GST_AUDIO_DECODER_SRC_PAD (atdec));
  output_caps = gst_caps_fixate (output_caps);

  gst_caps_set_simple (output_caps,
      "rate", G_TYPE_INT, (int) input_format.mSampleRate,
      "channels", G_TYPE_INT, input_format.mChannelsPerFrame, NULL);

  /* configure output_format from caps */
  gst_caps_to_at_format (output_caps, &output_format);

  /* set the format we want to negotiate downstream */
  gst_audio_info_from_caps (&output_info, output_caps);
  gst_audio_info_set_format (&output_info,
      output_format.mFormatFlags & kLinearPCMFormatFlagIsSignedInteger ?
      GST_AUDIO_FORMAT_S16LE : GST_AUDIO_FORMAT_F32LE,
      output_format.mSampleRate, output_format.mChannelsPerFrame, NULL);
  gst_audio_decoder_set_output_format (decoder, &output_info);
  gst_caps_unref (output_caps);

  status = AudioQueueNewOutput (&input_format, gst_atdec_buffer_emptied,
      atdec, NULL, NULL, 0, &atdec->queue);
  if (status)
    goto create_queue_error;

  /* FIXME: figure out how to map this properly */
  if (output_format.mChannelsPerFrame == 1)
    output_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
  else
    output_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;

  status = AudioQueueSetOfflineRenderFormat (atdec->queue,
      &output_format, &output_layout);
  if (status)
    goto set_format_error;

  status = AudioQueueStart (atdec->queue, NULL);
  if (status)
    goto start_error;

  timestamp.mFlags = kAudioTimeStampSampleTimeValid;
  timestamp.mSampleTime = 0;

  status =
      AudioQueueAllocateBuffer (atdec->queue, atdec->spf * output_info.bpf,
      &output_buffer);
  if (status)
    goto allocate_output_error;

  status = AudioQueueOfflineRender (atdec->queue, &timestamp, output_buffer, 0);
  if (status)
    goto offline_render_error;

  AudioQueueFreeBuffer (atdec->queue, output_buffer);

  return TRUE;

create_queue_error:
  GST_ELEMENT_ERROR (atdec, STREAM, FORMAT, (NULL),
      ("AudioQueueNewOutput returned error: %d", (gint) status));
  return FALSE;

set_format_error:
  GST_ELEMENT_ERROR (atdec, STREAM, FORMAT, (NULL),
      ("AudioQueueSetOfflineRenderFormat returned error: %d", (gint) status));
  gst_atdec_destroy_queue (atdec, FALSE);
  return FALSE;

start_error:
  GST_ELEMENT_ERROR (atdec, STREAM, FORMAT, (NULL),
      ("AudioQueueStart returned error: %d", (gint) status));
  gst_atdec_destroy_queue (atdec, FALSE);
  return FALSE;

allocate_output_error:
  GST_ELEMENT_ERROR (atdec, STREAM, FORMAT, (NULL),
      ("AudioQueueAllocateBuffer returned error: %d", (gint) status));
  gst_atdec_destroy_queue (atdec, FALSE);
  return FALSE;

offline_render_error:
  GST_ELEMENT_ERROR (atdec, STREAM, FORMAT, (NULL),
      ("AudioQueueOfflineRender returned error: %d", (gint) status));
  AudioQueueFreeBuffer (atdec->queue, output_buffer);
  gst_atdec_destroy_queue (atdec, FALSE);
  return FALSE;
}

static void
gst_atdec_buffer_emptied (void *user_data, AudioQueueRef queue,
    AudioQueueBufferRef buffer)
{
  AudioQueueFreeBuffer (queue, buffer);
}

static GstFlowReturn
gst_atdec_offline_render (GstATDec * atdec, GstAudioInfo * audio_info)
{
  OSStatus status;
  AudioTimeStamp timestamp = { 0 };
  AudioQueueBufferRef output_buffer;
  GstFlowReturn flow_ret = GST_FLOW_OK;
  GstBuffer *out;
  guint out_frames;

  /* figure out how many frames we need to pull out of the queue */
  out_frames = atdec->input_position - atdec->output_position;
  if (out_frames > atdec->spf)
    out_frames = atdec->spf;
  status = AudioQueueAllocateBuffer (atdec->queue, out_frames * audio_info->bpf,
      &output_buffer);
  if (status)
    goto allocate_output_failed;

  /* pull the frames */
  timestamp.mFlags = kAudioTimeStampSampleTimeValid;
  timestamp.mSampleTime = atdec->output_position;
  status =
      AudioQueueOfflineRender (atdec->queue, &timestamp, output_buffer,
      out_frames);
  if (status)
    goto offline_render_failed;

  if (output_buffer->mAudioDataByteSize) {
    if (output_buffer->mAudioDataByteSize % audio_info->bpf != 0)
      goto invalid_buffer_size;

    GST_DEBUG_OBJECT (atdec,
        "Got output buffer of size %u at position %" G_GUINT64_FORMAT,
        (guint) output_buffer->mAudioDataByteSize, atdec->output_position);
    atdec->output_position +=
        output_buffer->mAudioDataByteSize / audio_info->bpf;

    out =
        gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (atdec),
        output_buffer->mAudioDataByteSize);

    gst_buffer_fill (out, 0, output_buffer->mAudioData,
        output_buffer->mAudioDataByteSize);

    flow_ret =
        gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (atdec), out, 1);
    GST_DEBUG_OBJECT (atdec, "Finished buffer: %s",
        gst_flow_get_name (flow_ret));
  } else {
    GST_DEBUG_OBJECT (atdec, "Got empty output buffer");
    flow_ret = GST_FLOW_CUSTOM_SUCCESS;
  }

  AudioQueueFreeBuffer (atdec->queue, output_buffer);

  return flow_ret;

allocate_output_failed:
  {
    GST_ELEMENT_ERROR (atdec, STREAM, DECODE, (NULL),
        ("AudioQueueAllocateBuffer returned error: %d", (gint) status));
    return GST_FLOW_ERROR;
  }

offline_render_failed:
  {
    AudioQueueFreeBuffer (atdec->queue, output_buffer);

    GST_AUDIO_DECODER_ERROR (atdec, 1, STREAM, DECODE, (NULL),
        ("AudioQueueOfflineRender returned error: %d", (gint) status),
        flow_ret);

    return flow_ret;
  }

invalid_buffer_size:
  {
    GST_AUDIO_DECODER_ERROR (atdec, 1, STREAM, DECODE, (NULL),
        ("AudioQueueOfflineRender returned invalid buffer size: %u (bpf %d)",
            (guint) output_buffer->mAudioDataByteSize, audio_info->bpf),
        flow_ret);

    AudioQueueFreeBuffer (atdec->queue, output_buffer);

    return flow_ret;
  }
}

static GstFlowReturn
gst_atdec_handle_frame (GstAudioDecoder * decoder, GstBuffer * buffer)
{
  OSStatus status;
  AudioStreamPacketDescription packet;
  AudioQueueBufferRef input_buffer;
  GstAudioInfo *audio_info;
  int size;
  GstFlowReturn flow_ret = GST_FLOW_OK;
  GstATDec *atdec = GST_ATDEC (decoder);

  audio_info = gst_audio_decoder_get_audio_info (decoder);

  if (buffer == NULL) {
    GST_DEBUG_OBJECT (atdec, "Draining");
    AudioQueueFlush (atdec->queue);

    while (atdec->input_position > atdec->output_position
        && flow_ret == GST_FLOW_OK) {
      flow_ret = gst_atdec_offline_render (atdec, audio_info);
    }

    if (flow_ret == GST_FLOW_CUSTOM_SUCCESS)
      flow_ret = GST_FLOW_OK;

    return flow_ret;
  }

  /* copy the input buffer into an AudioQueueBuffer */
  size = gst_buffer_get_size (buffer);
  GST_DEBUG_OBJECT (atdec,
      "Handling buffer of size %u at timestamp %" GST_TIME_FORMAT, (guint) size,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
  status = AudioQueueAllocateBuffer (atdec->queue, size, &input_buffer);
  if (status)
    goto allocate_input_failed;
  gst_buffer_extract (buffer, 0, input_buffer->mAudioData, size);
  input_buffer->mAudioDataByteSize = size;

  /* assume framed input */
  packet.mStartOffset = 0;
  packet.mVariableFramesInPacket = 1;
  packet.mDataByteSize = size;

  /* enqueue the buffer. It will get free'd once the gst_atdec_buffer_emptied
   * callback is called
   */
  status = AudioQueueEnqueueBuffer (atdec->queue, input_buffer, 1, &packet);
  if (status)
    goto enqueue_buffer_failed;

  atdec->input_position += atdec->spf;

  flow_ret = gst_atdec_offline_render (atdec, audio_info);
  if (flow_ret == GST_FLOW_CUSTOM_SUCCESS)
    flow_ret = GST_FLOW_OK;

  return flow_ret;

allocate_input_failed:
  {
    GST_ELEMENT_ERROR (atdec, STREAM, DECODE, (NULL),
        ("AudioQueueAllocateBuffer returned error: %d", (gint) status));
    return GST_FLOW_ERROR;
  }

enqueue_buffer_failed:
  {
    GST_AUDIO_DECODER_ERROR (atdec, 1, STREAM, DECODE, (NULL),
        ("AudioQueueEnqueueBuffer returned error: %d", (gint) status),
        flow_ret);
    return flow_ret;
  }
}

static void
gst_atdec_flush (GstAudioDecoder * decoder, gboolean hard)
{
  GstATDec *atdec = GST_ATDEC (decoder);

  GST_DEBUG_OBJECT (atdec, "Flushing");
  AudioQueueReset (atdec->queue);
  atdec->output_position = 0;
  atdec->input_position = 0;
}
