/* 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_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&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)
{
  /* ckID == 'FORM' */
  gst_byte_writer_put_uint32_le_unchecked (writer,
      GST_MAKE_FOURCC ('F', 'O', 'R', 'M'));
  /* ckSize is currently bogus but we'll know what it is later */
  gst_byte_writer_put_uint32_be_unchecked (writer,
      audio_data_size + AIFF_HEADER_LEN - 8);
  /* 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);

  writer = gst_byte_writer_new_with_size (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_free_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:{
      GST_DEBUG_OBJECT (aiffmux, "got EOS");

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