/* GStreamer AIFF muxer
 * Copyright (C) 2009 Robert Swain <robert.swain@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * 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.
 */

/**
 * SECTION:element-aiffmux
 *
 * Format an audio stream into the Audio Interchange File Format
 *
 */

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

#include <string.h>
#include <math.h>
#include <gst/gst.h>
#include <gst/base/gstbytewriter.h>

#include "aiffmux.h"

GST_DEBUG_CATEGORY (aiffmux_debug);
#define GST_CAT_DEFAULT aiffmux_debug

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = { S8, S16BE, S24BE, S32BE },"
        "channels = (int) [ 1, MAX ], " "rate = (int) [ 1, MAX ]")
    );

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-aiff")
    );

#define gst_aiff_mux_parent_class parent_class
G_DEFINE_TYPE (GstAiffMux, gst_aiff_mux, GST_TYPE_ELEMENT);

static GstStateChangeReturn
gst_aiff_mux_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstAiffMux *aiffmux = GST_AIFF_MUX (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_audio_info_init (&aiffmux->info);
      aiffmux->length = 0;
      aiffmux->sent_header = FALSE;
      aiffmux->overflow = FALSE;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret != GST_STATE_CHANGE_SUCCESS)
    return ret;

  return ret;
}

static void
gst_aiff_mux_class_init (GstAiffMuxClass * klass)
{
  GstElementClass *gstelement_class;

  gstelement_class = (GstElementClass *) klass;

  gst_element_class_set_static_metadata (gstelement_class,
      "AIFF audio muxer", "Muxer/Audio", "Multiplex raw audio into AIFF",
      "Robert Swain <robert.swain@gmail.com>");

  gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
  gst_element_class_add_static_pad_template (gstelement_class, &sink_factory);

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_aiff_mux_change_state);
}

#define AIFF_FORM_HEADER_LEN 8 + 4
#define AIFF_COMM_HEADER_LEN 8 + 18
#define AIFF_SSND_HEADER_LEN 8 + 8
#define AIFF_HEADER_LEN \
  (AIFF_FORM_HEADER_LEN + AIFF_COMM_HEADER_LEN + AIFF_SSND_HEADER_LEN)

static void
gst_aiff_mux_write_form_header (GstAiffMux * aiffmux, guint32 audio_data_size,
    GstByteWriter * writer)
{
  guint64 cur_size;

  /* ckID == 'FORM' */
  gst_byte_writer_put_uint32_le_unchecked (writer,
      GST_MAKE_FOURCC ('F', 'O', 'R', 'M'));

  /* AIFF chunks must be even aligned */
  cur_size = AIFF_HEADER_LEN - 8 + audio_data_size;
  if ((cur_size & 1) && cur_size + 1 < G_MAXUINT32) {
    cur_size += 1;
  }

  gst_byte_writer_put_uint32_be_unchecked (writer, cur_size);
  /* formType == 'AIFF' */
  gst_byte_writer_put_uint32_le_unchecked (writer,
      GST_MAKE_FOURCC ('A', 'I', 'F', 'F'));
}

/*
 * BEGIN: Code borrowed from FFmpeg's libavutil/intfloat_readwrite.{c,h}
 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
 */

/* IEEE 80 bits extended float */
typedef struct AVExtFloat
{
  guint8 exponent[2];
  guint8 mantissa[8];
} AVExtFloat;

/* Courtesy http://www.devx.com/tips/Tip/42853 */
static inline gint
gst_aiff_mux_isinf (gdouble x)
{
  volatile gdouble temp = x;
  if ((temp == x) && ((temp - x) != 0.0))
    return (x < 0.0 ? -1 : 1);
  else
    return 0;
}

static void
gst_aiff_mux_write_ext (GstByteWriter * writer, double d)
{
  struct AVExtFloat ext = { {0} };
  gint e, i;
  gdouble f;
  guint64 m;

  f = fabs (frexp (d, &e));
  if (f >= 0.5 && f < 1) {
    e += 16382;
    ext.exponent[0] = e >> 8;
    ext.exponent[1] = e;
    m = (guint64) ldexp (f, 64);
    for (i = 0; i < 8; i++)
      ext.mantissa[i] = m >> (56 - (i << 3));
  } else if (f != 0.0) {
    ext.exponent[0] = 0x7f;
    ext.exponent[1] = 0xff;
    if (!gst_aiff_mux_isinf (f))
      ext.mantissa[0] = ~0;
  }
  if (d < 0)
    ext.exponent[0] |= 0x80;

  gst_byte_writer_put_data_unchecked (writer, ext.exponent, 2);
  gst_byte_writer_put_data_unchecked (writer, ext.mantissa, 8);
}

/*
 * END: Code borrowed from FFmpeg's libavutil/intfloat_readwrite.{c,h}
 */

static void
gst_aiff_mux_write_comm_header (GstAiffMux * aiffmux, guint32 audio_data_size,
    GstByteWriter * writer)
{
  guint16 channels;
  guint16 width, depth;
  gdouble rate;

  channels = GST_AUDIO_INFO_CHANNELS (&aiffmux->info);
  width = GST_AUDIO_INFO_WIDTH (&aiffmux->info);
  depth = GST_AUDIO_INFO_DEPTH (&aiffmux->info);
  rate = GST_AUDIO_INFO_RATE (&aiffmux->info);

  gst_byte_writer_put_uint32_le_unchecked (writer,
      GST_MAKE_FOURCC ('C', 'O', 'M', 'M'));
  gst_byte_writer_put_uint32_be_unchecked (writer, 18);
  gst_byte_writer_put_uint16_be_unchecked (writer, channels);
  /* numSampleFrames value will be overwritten when known */
  gst_byte_writer_put_uint32_be_unchecked (writer,
      audio_data_size / (width / 8 * channels));
  gst_byte_writer_put_uint16_be_unchecked (writer, depth);
  gst_aiff_mux_write_ext (writer, rate);
}

static void
gst_aiff_mux_write_ssnd_header (GstAiffMux * aiffmux, guint32 audio_data_size,
    GstByteWriter * writer)
{
  gst_byte_writer_put_uint32_le_unchecked (writer,
      GST_MAKE_FOURCC ('S', 'S', 'N', 'D'));
  /* ckSize will be overwritten when known */
  gst_byte_writer_put_uint32_be_unchecked (writer,
      audio_data_size + AIFF_SSND_HEADER_LEN - 8);
  /* offset and blockSize are set to 0 as we don't support block-aligned sample data yet */
  gst_byte_writer_put_uint32_be_unchecked (writer, 0);
  gst_byte_writer_put_uint32_be_unchecked (writer, 0);
}

static GstFlowReturn
gst_aiff_mux_push_header (GstAiffMux * aiffmux, guint32 audio_data_size)
{
  GstFlowReturn ret;
  GstBuffer *outbuf;
  GstByteWriter writer;
  GstSegment seg;

  /* seek to beginning of file */
  gst_segment_init (&seg, GST_FORMAT_BYTES);

  if (gst_pad_push_event (aiffmux->srcpad,
          gst_event_new_segment (&seg)) == FALSE) {
    GST_ELEMENT_WARNING (aiffmux, STREAM, MUX,
        ("An output stream seeking error occurred when multiplexing."),
        ("Failed to seek to beginning of stream to write header."));
  }

  GST_DEBUG_OBJECT (aiffmux, "writing header with datasize=%u",
      audio_data_size);

  gst_byte_writer_init_with_size (&writer, AIFF_HEADER_LEN, TRUE);

  gst_aiff_mux_write_form_header (aiffmux, audio_data_size, &writer);
  gst_aiff_mux_write_comm_header (aiffmux, audio_data_size, &writer);
  gst_aiff_mux_write_ssnd_header (aiffmux, audio_data_size, &writer);

  outbuf = gst_byte_writer_reset_and_get_buffer (&writer);

  ret = gst_pad_push (aiffmux->srcpad, outbuf);

  if (ret != GST_FLOW_OK) {
    GST_WARNING_OBJECT (aiffmux, "push header failed: flow = %s",
        gst_flow_get_name (ret));
  }

  return ret;
}

static GstFlowReturn
gst_aiff_mux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstAiffMux *aiffmux = GST_AIFF_MUX (parent);
  GstFlowReturn flow = GST_FLOW_OK;
  guint64 cur_size;
  gsize buf_size;

  if (!GST_AUDIO_INFO_CHANNELS (&aiffmux->info))
    goto not_negotiated;

  if (G_UNLIKELY (aiffmux->overflow))
    goto overflow;

  if (!aiffmux->sent_header) {
    /* use bogus size initially, we'll write the real
     * header when we get EOS and know the exact length */
    flow = gst_aiff_mux_push_header (aiffmux, 0x7FFF0000);
    if (flow != GST_FLOW_OK)
      goto flow_error;

    GST_DEBUG_OBJECT (aiffmux, "wrote dummy header");
    aiffmux->sent_header = TRUE;
  }

  /* AIFF has an audio data size limit of slightly under 4 GB.
     A value of audiosize + AIFF_HEADER_LEN - 8 is written, so
     I'll error out if writing data that makes this overflow. */
  cur_size = aiffmux->length + AIFF_HEADER_LEN - 8;
  buf_size = gst_buffer_get_size (buf);

  if (G_UNLIKELY (cur_size + buf_size >= G_MAXUINT32)) {
    GST_ERROR_OBJECT (aiffmux, "AIFF only supports about 4 GB worth of "
        "audio data, dropping any further data on the floor");
    GST_ELEMENT_WARNING (aiffmux, STREAM, MUX, ("AIFF has a 4GB size limit"),
        ("AIFF only supports about 4 GB worth of audio data, "
            "dropping any further data on the floor"));
    aiffmux->overflow = TRUE;
    goto overflow;
  }

  GST_LOG_OBJECT (aiffmux,
      "pushing %" G_GSIZE_FORMAT " bytes raw audio, ts=%" GST_TIME_FORMAT,
      buf_size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));

  buf = gst_buffer_make_writable (buf);

  GST_BUFFER_OFFSET (buf) = AIFF_HEADER_LEN + aiffmux->length;
  GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;

  aiffmux->length += buf_size;

  flow = gst_pad_push (aiffmux->srcpad, buf);

  return flow;

not_negotiated:
  {
    GST_WARNING_OBJECT (aiffmux, "no input format negotiated");
    gst_buffer_unref (buf);
    return GST_FLOW_NOT_NEGOTIATED;
  }
overflow:
  {
    GST_WARNING_OBJECT (aiffmux, "output file too large, dropping buffer");
    gst_buffer_unref (buf);
    return GST_FLOW_OK;
  }
flow_error:
  {
    GST_DEBUG_OBJECT (aiffmux, "got flow error %s", gst_flow_get_name (flow));
    gst_buffer_unref (buf);
    return flow;
  }
}

static gboolean
gst_aiff_mux_set_caps (GstAiffMux * aiffmux, GstCaps * caps)
{
  GstCaps *outcaps;
  GstAudioInfo info;

  if (aiffmux->sent_header) {
    GST_WARNING_OBJECT (aiffmux, "cannot change format mid-stream");
    return FALSE;
  }

  GST_DEBUG_OBJECT (aiffmux, "got caps: %" GST_PTR_FORMAT, caps);

  if (!gst_audio_info_from_caps (&info, caps)) {
    GST_WARNING_OBJECT (aiffmux, "caps incomplete");
    return FALSE;
  }

  aiffmux->info = info;

  GST_LOG_OBJECT (aiffmux,
      "accepted caps: chans=%d depth=%d rate=%d",
      GST_AUDIO_INFO_CHANNELS (&info), GST_AUDIO_INFO_DEPTH (&info),
      GST_AUDIO_INFO_RATE (&info));

  outcaps = gst_static_pad_template_get_caps (&src_factory);
  gst_pad_push_event (aiffmux->srcpad, gst_event_new_caps (outcaps));
  gst_caps_unref (outcaps);

  return TRUE;
}


static gboolean
gst_aiff_mux_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  GstAiffMux *aiffmux;

  aiffmux = GST_AIFF_MUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:{
      guint64 cur_size;
      GST_DEBUG_OBJECT (aiffmux, "got EOS");

      cur_size = aiffmux->length + AIFF_HEADER_LEN - 8;

      /* ID3 chunk must be even aligned */
      if ((aiffmux->length & 1) && cur_size + 1 < G_MAXUINT32) {
        GstFlowReturn ret;
        guint8 *data = g_new0 (guint8, 1);
        GstBuffer *buffer = gst_buffer_new_wrapped (data, 1);
        GST_BUFFER_OFFSET (buffer) = AIFF_HEADER_LEN + aiffmux->length;
        GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
        ret = gst_pad_push (aiffmux->srcpad, buffer);
        if (ret != GST_FLOW_OK) {
          GST_WARNING_OBJECT (aiffmux, "failed to push padding byte: %s",
              gst_flow_get_name (ret));
        }
      }

      /* write header with correct length values */
      gst_aiff_mux_push_header (aiffmux, aiffmux->length);

      /* and forward the EOS event */
      res = gst_pad_event_default (pad, parent, event);
      break;
    }
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_aiff_mux_set_caps (aiffmux, caps);
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_SEGMENT:
      /* Just drop it, it's probably in TIME format
       * anyway. We'll send our own newsegment event */
      gst_event_unref (event);
      break;
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }
  return res;
}

static void
gst_aiff_mux_init (GstAiffMux * aiffmux)
{
  aiffmux->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
  gst_pad_set_chain_function (aiffmux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_aiff_mux_chain));
  gst_pad_set_event_function (aiffmux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_aiff_mux_event));
  gst_element_add_pad (GST_ELEMENT (aiffmux), aiffmux->sinkpad);

  aiffmux->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
  gst_pad_use_fixed_caps (aiffmux->srcpad);
  gst_element_add_pad (GST_ELEMENT (aiffmux), aiffmux->srcpad);
}
