/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
/* GStreamer AIFF parser
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *               <2006> Nokia Corporation, Stefan Kost <stefan.kost@nokia.com>.
 *               <2008> Pioneers of the Inevitable <songbird@songbirdnest.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.
 */

/**
 * SECTION:element-aiffparse
 *
 * <refsect2>
 * <para>
 * Parse a .aiff file into raw or compressed audio.
 * </para>
 * <para>
 * The aiffparse element supports both push and pull mode operations, making it
 * possible to stream from a network source.
 * </para>
 * <title>Example launch line</title>
 * <para>
 * <programlisting>
 * gst-launch-1.0 filesrc location=sine.aiff ! aiffparse ! audioconvert ! alsasink
 * </programlisting>
 * Read a aiff file and output to the soundcard using the ALSA element. The
 * aiff file is assumed to contain raw uncompressed samples.
 * </para>
 * <para>
 * <programlisting>
 * gst-launch-1.0 souphttpsrc location=http://www.example.org/sine.aiff ! queue ! aiffparse ! audioconvert ! alsasink
 * </programlisting>
 * Stream data from a network url.
 * </para>
 * </refsect2>
 */

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

#include <string.h>
#include <math.h>

#include "aiffparse.h"
#include <gst/audio/audio.h>
#include <gst/tag/tag.h>
#include <gst/gst-i18n-plugin.h>

GST_DEBUG_CATEGORY (aiffparse_debug);
#define GST_CAT_DEFAULT (aiffparse_debug)

static void gst_aiff_parse_dispose (GObject * object);

static gboolean gst_aiff_parse_sink_activate (GstPad * sinkpad,
    GstObject * parent);
static gboolean gst_aiff_parse_sink_activate_mode (GstPad * sinkpad,
    GstObject * parent, GstPadMode mode, gboolean active);
static gboolean gst_aiff_parse_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * buf);
static gboolean gst_aiff_parse_send_event (GstElement * element,
    GstEvent * event);
static GstStateChangeReturn gst_aiff_parse_change_state (GstElement * element,
    GstStateChange transition);

static gboolean gst_aiff_parse_pad_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_aiff_parse_pad_convert (GstPad * pad,
    GstFormat src_format,
    gint64 src_value, GstFormat * dest_format, gint64 * dest_value);

static GstFlowReturn gst_aiff_parse_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static void gst_aiff_parse_loop (GstPad * pad);
static gboolean gst_aiff_parse_srcpad_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static GstStaticPadTemplate sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-aiff")
    );

static GstStaticPadTemplate src_template_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE ("{ S8, S16BE, S16LE, S24BE, S24LE, "
            "S32LE, S32BE, F32BE, F64BE }"))
    );

#define MAX_BUFFER_SIZE 4096

#define gst_aiff_parse_parent_class parent_class
G_DEFINE_TYPE (GstAiffParse, gst_aiff_parse, GST_TYPE_ELEMENT);

static void
gst_aiff_parse_class_init (GstAiffParseClass * klass)
{
  GstElementClass *gstelement_class;
  GObjectClass *object_class;

  gstelement_class = (GstElementClass *) klass;
  object_class = (GObjectClass *) klass;

  object_class->dispose = gst_aiff_parse_dispose;

  gst_element_class_add_static_pad_template (gstelement_class,
      &sink_template_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &src_template_factory);

  gst_element_class_set_static_metadata (gstelement_class,
      "AIFF audio demuxer", "Codec/Demuxer/Audio",
      "Parse a .aiff file into raw audio",
      "Pioneers of the Inevitable <songbird@songbirdnest.com>");

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_aiff_parse_change_state);
  gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_aiff_parse_send_event);
}

static void
gst_aiff_parse_reset (GstAiffParse * aiff)
{
  aiff->state = AIFF_PARSE_START;

  /* These will all be set correctly in the fmt chunk */
  aiff->rate = 0;
  aiff->width = 0;
  aiff->depth = 0;
  aiff->channels = 0;
  aiff->bps = 0;
  aiff->offset = 0;
  aiff->end_offset = 0;
  aiff->dataleft = 0;
  aiff->datasize = 0;
  aiff->datastart = 0;
  aiff->duration = 0;
  aiff->got_comm = FALSE;

  if (aiff->seek_event)
    gst_event_unref (aiff->seek_event);
  aiff->seek_event = NULL;
  if (aiff->adapter) {
    gst_adapter_clear (aiff->adapter);
    aiff->adapter = NULL;
  }

  if (aiff->tags != NULL) {
    gst_tag_list_unref (aiff->tags);
    aiff->tags = NULL;
  }
}

static void
gst_aiff_parse_dispose (GObject * object)
{
  GstAiffParse *aiff = GST_AIFF_PARSE (object);

  GST_DEBUG_OBJECT (aiff, "AIFF: Dispose");
  gst_aiff_parse_reset (aiff);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gst_aiff_parse_init (GstAiffParse * aiffparse)
{
  gst_aiff_parse_reset (aiffparse);

  /* sink */
  aiffparse->sinkpad =
      gst_pad_new_from_static_template (&sink_template_factory, "sink");
  gst_pad_set_activate_function (aiffparse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_aiff_parse_sink_activate));
  gst_pad_set_activatemode_function (aiffparse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_aiff_parse_sink_activate_mode));
  gst_pad_set_event_function (aiffparse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_aiff_parse_sink_event));
  gst_pad_set_chain_function (aiffparse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_aiff_parse_chain));
  gst_element_add_pad (GST_ELEMENT_CAST (aiffparse), aiffparse->sinkpad);

  /* source */
  aiffparse->srcpad =
      gst_pad_new_from_static_template (&src_template_factory, "src");
  gst_pad_use_fixed_caps (aiffparse->srcpad);
  gst_pad_set_query_function (aiffparse->srcpad,
      GST_DEBUG_FUNCPTR (gst_aiff_parse_pad_query));
  gst_pad_set_event_function (aiffparse->srcpad,
      GST_DEBUG_FUNCPTR (gst_aiff_parse_srcpad_event));
  gst_element_add_pad (GST_ELEMENT_CAST (aiffparse), aiffparse->srcpad);
}

static gboolean
gst_aiff_parse_parse_file_header (GstAiffParse * aiff, GstBuffer * buf)
{
  guint32 header, type = 0;
  GstMapInfo info;

  if (!gst_buffer_map (buf, &info, GST_MAP_READ)) {
    GST_WARNING_OBJECT (aiff, "Could not map buffer");
    goto not_aiff;
  }

  if (info.size < 12) {
    GST_WARNING_OBJECT (aiff, "Buffer too short");
    gst_buffer_unmap (buf, &info);
    goto not_aiff;
  }

  header = GST_READ_UINT32_LE (info.data);
  type = GST_READ_UINT32_LE (info.data + 8);
  gst_buffer_unmap (buf, &info);

  if (header != GST_MAKE_FOURCC ('F', 'O', 'R', 'M'))
    goto not_aiff;

  if (type == GST_MAKE_FOURCC ('A', 'I', 'F', 'F'))
    aiff->is_aifc = FALSE;
  else if (type == GST_MAKE_FOURCC ('A', 'I', 'F', 'C'))
    aiff->is_aifc = TRUE;
  else
    goto not_aiff;

  gst_buffer_unref (buf);
  return TRUE;

  /* ERRORS */
not_aiff:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, WRONG_TYPE, (NULL),
        ("File is not an AIFF file: 0x%" G_GINT32_MODIFIER "x", type));
    gst_buffer_unref (buf);
    return FALSE;
  }
}

static GstFlowReturn
gst_aiff_parse_stream_init (GstAiffParse * aiff)
{
  GstFlowReturn res;
  GstBuffer *buf = NULL;

  if ((res = gst_pad_pull_range (aiff->sinkpad,
              aiff->offset, 12, &buf)) != GST_FLOW_OK)
    return res;
  else if (!gst_aiff_parse_parse_file_header (aiff, buf))
    return GST_FLOW_ERROR;

  aiff->offset += 12;

  return GST_FLOW_OK;
}

static gboolean
gst_aiff_parse_time_to_bytepos (GstAiffParse * aiff, gint64 ts,
    gint64 * bytepos)
{
  /* -1 always maps to -1 */
  if (ts == -1) {
    *bytepos = -1;
    return TRUE;
  }

  /* 0 always maps to 0 */
  if (ts == 0) {
    *bytepos = 0;
    return TRUE;
  }

  if (aiff->bps > 0) {
    *bytepos = gst_util_uint64_scale_ceil (ts, (guint64) aiff->bps, GST_SECOND);
    return TRUE;
  }

  GST_WARNING_OBJECT (aiff, "No valid bps to convert position");

  return FALSE;
}

/* This function is used to perform seeks on the element in
 * pull mode.
 *
 * It also works when event is NULL, in which case it will just
 * start from the last configured segment. This technique is
 * used when activating the element and to perform the seek in
 * READY.
 */
static gboolean
gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event,
    gboolean starting)
{
  gboolean res;
  gdouble rate;
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType start_type = GST_SEEK_TYPE_NONE, stop_type;
  gint64 start, stop, upstream_size;
  gboolean flush;
  gboolean update;
  GstSegment seeksegment = { 0, };
  gint64 position;

  if (event) {
    GST_DEBUG_OBJECT (aiff, "doing seek with event");

    gst_event_parse_seek (event, &rate, &format, &flags,
        &start_type, &start, &stop_type, &stop);

    /* no negative rates yet */
    if (rate < 0.0)
      goto negative_rate;

    if (format != aiff->segment.format) {
      GST_INFO_OBJECT (aiff, "converting seek-event from %s to %s",
          gst_format_get_name (format),
          gst_format_get_name (aiff->segment.format));
      res = TRUE;
      if (start_type != GST_SEEK_TYPE_NONE)
        res =
            gst_pad_query_convert (aiff->srcpad, format, start,
            aiff->segment.format, &start);
      if (res && stop_type != GST_SEEK_TYPE_NONE)
        res =
            gst_pad_query_convert (aiff->srcpad, format, stop,
            aiff->segment.format, &stop);
      if (!res)
        goto no_format;

      format = aiff->segment.format;
    }
  } else {
    GST_DEBUG_OBJECT (aiff, "doing seek without event");
    flags = 0;
    rate = 1.0;
    start = 0;
    start_type = GST_SEEK_TYPE_SET;
    stop = -1;
    stop_type = GST_SEEK_TYPE_SET;
  }

  /* get flush flag */
  flush = flags & GST_SEEK_FLAG_FLUSH;

  if (aiff->streaming && !starting) {
    GstEvent *new_event;

    /* streaming seek */
    if ((start_type != GST_SEEK_TYPE_NONE)) {
      /* bring offset to bytes, if the bps is 0, we have the segment in BYTES and
       * we can just copy the position. If not, we use the bps to convert TIME to
       * bytes. */
      if (aiff->bps > 0)
        start =
            gst_util_uint64_scale_ceil (start, (guint64) aiff->bps, GST_SECOND);
      start -= (start % aiff->bytes_per_sample);
      start += aiff->datastart;
    }

    if (stop_type != GST_SEEK_TYPE_NONE) {
      if (aiff->bps > 0)
        stop =
            gst_util_uint64_scale_ceil (stop, (guint64) aiff->bps, GST_SECOND);
      stop -= (stop % aiff->bytes_per_sample);
      stop += aiff->datastart;
    }

    /* make sure filesize is not exceeded due to rounding errors or so,
     * same precaution as in _stream_headers */
    if (gst_pad_peer_query_duration (aiff->sinkpad, GST_FORMAT_BYTES,
            &upstream_size))
      stop = MIN (stop, upstream_size);

    if (stop >= 0 && stop <= start)
      stop = start;

    new_event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags,
        start_type, start, stop_type, stop);

    res = gst_pad_push_event (aiff->sinkpad, new_event);
  } else {
    /* now we need to make sure the streaming thread is stopped. We do this by
     * either sending a FLUSH_START event downstream which will cause the
     * streaming thread to stop with a FLUSHING.
     * For a non-flushing seek we simply pause the task, which will happen as soon
     * as it completes one iteration (and thus might block when the sink is
     * blocking in preroll). */
    if (flush) {
      GST_DEBUG_OBJECT (aiff, "sending flush start");
      gst_pad_push_event (aiff->srcpad, gst_event_new_flush_start ());
    } else {
      gst_pad_pause_task (aiff->sinkpad);
    }

    /* we should now be able to grab the streaming thread because we stopped it
     * with the above flush/pause code */
    GST_PAD_STREAM_LOCK (aiff->sinkpad);

    /* save current position */
    position = aiff->segment.position;

    GST_DEBUG_OBJECT (aiff, "stopped streaming at %" G_GINT64_FORMAT, position);

    /* copy segment, we need this because we still need the old
     * segment when we close the current segment. */
    memcpy (&seeksegment, &aiff->segment, sizeof (GstSegment));

    /* configure the seek parameters in the seeksegment. We will then have the
     * right values in the segment to perform the seek */
    if (event) {
      GST_DEBUG_OBJECT (aiff, "configuring seek");
      gst_segment_do_seek (&seeksegment, rate, format, flags,
          start_type, start, stop_type, stop, &update);
    }

    /* figure out the last position we need to play. If it's configured (stop !=
     * -1), use that, else we play until the total duration of the file */
    if ((stop = seeksegment.stop) == -1)
      stop = seeksegment.duration;

    GST_DEBUG_OBJECT (aiff, "start_type =%d", start_type);
    if ((start_type != GST_SEEK_TYPE_NONE)) {
      /* bring offset to bytes, if the bps is 0, we have the segment in BYTES and
       * we can just copy the position. If not, we use the bps to convert TIME to
       * bytes. */
      if (aiff->bps > 0)
        aiff->offset =
            gst_util_uint64_scale_ceil (seeksegment.position,
            (guint64) aiff->bps, GST_SECOND);
      else
        aiff->offset = seeksegment.position;
      GST_LOG_OBJECT (aiff, "offset=%" G_GUINT64_FORMAT, aiff->offset);
      aiff->offset -= (aiff->offset % aiff->bytes_per_sample);
      GST_LOG_OBJECT (aiff, "offset=%" G_GUINT64_FORMAT, aiff->offset);
      aiff->offset += aiff->datastart;
      GST_LOG_OBJECT (aiff, "offset=%" G_GUINT64_FORMAT, aiff->offset);
    } else {
      GST_LOG_OBJECT (aiff, "continue from offset=%" G_GUINT64_FORMAT,
          aiff->offset);
    }

    if (stop_type != GST_SEEK_TYPE_NONE) {
      if (aiff->bps > 0)
        aiff->end_offset =
            gst_util_uint64_scale_ceil (stop, (guint64) aiff->bps, GST_SECOND);
      else
        aiff->end_offset = stop;
      GST_LOG_OBJECT (aiff, "end_offset=%" G_GUINT64_FORMAT, aiff->end_offset);
      aiff->end_offset -= (aiff->end_offset % aiff->bytes_per_sample);
      GST_LOG_OBJECT (aiff, "end_offset=%" G_GUINT64_FORMAT, aiff->end_offset);
      aiff->end_offset += aiff->datastart;
      GST_LOG_OBJECT (aiff, "end_offset=%" G_GUINT64_FORMAT, aiff->end_offset);
    } else {
      GST_LOG_OBJECT (aiff, "continue to end_offset=%" G_GUINT64_FORMAT,
          aiff->end_offset);
    }

    /* make sure filesize is not exceeded due to rounding errors or so,
     * same precaution as in _stream_headers */
    if (gst_pad_peer_query_duration (aiff->sinkpad, GST_FORMAT_BYTES,
            &upstream_size))
      aiff->end_offset = MIN (aiff->end_offset, upstream_size);

    /* this is the range of bytes we will use for playback */
    aiff->offset = MIN (aiff->offset, aiff->end_offset);
    aiff->dataleft = aiff->end_offset - aiff->offset;

    GST_DEBUG_OBJECT (aiff,
        "seek: rate %lf, offset %" G_GUINT64_FORMAT ", end %" G_GUINT64_FORMAT
        ", segment %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT, rate,
        aiff->offset, aiff->end_offset, GST_TIME_ARGS (seeksegment.start),
        GST_TIME_ARGS (stop));

    /* prepare for streaming again */
    if (flush) {
      /* if we sent a FLUSH_START, we now send a FLUSH_STOP */
      GST_DEBUG_OBJECT (aiff, "sending flush stop");
      gst_pad_push_event (aiff->srcpad, gst_event_new_flush_stop (TRUE));
    }

    /* now we did the seek and can activate the new segment values */
    memcpy (&aiff->segment, &seeksegment, sizeof (GstSegment));

    /* if we're doing a segment seek, post a SEGMENT_START message */
    if (aiff->segment.flags & GST_SEEK_FLAG_SEGMENT) {
      gst_element_post_message (GST_ELEMENT_CAST (aiff),
          gst_message_new_segment_start (GST_OBJECT_CAST (aiff),
              aiff->segment.format, aiff->segment.position));
    }

    /* now create the segment */
    GST_DEBUG_OBJECT (aiff, "Creating segment from %" G_GINT64_FORMAT
        " to %" G_GINT64_FORMAT, aiff->segment.position, stop);

    /* store the segment event so it can be sent from the streaming thread. */
    if (aiff->start_segment)
      gst_event_unref (aiff->start_segment);
    aiff->start_segment = gst_event_new_segment (&aiff->segment);

    /* mark discont if we are going to stream from another position. */
    if (position != aiff->segment.position) {
      GST_DEBUG_OBJECT (aiff,
          "mark DISCONT, we did a seek to another position");
      aiff->discont = TRUE;
    }

    /* and start the streaming task again */
    aiff->segment_running = TRUE;
    if (!aiff->streaming) {
      gst_pad_start_task (aiff->sinkpad, (GstTaskFunction) gst_aiff_parse_loop,
          aiff->sinkpad, NULL);
    }

    GST_PAD_STREAM_UNLOCK (aiff->sinkpad);

    res = TRUE;
  }

  return res;

  /* ERRORS */
negative_rate:
  {
    GST_DEBUG_OBJECT (aiff, "negative playback rates are not supported yet.");
    return FALSE;
  }
no_format:
  {
    GST_DEBUG_OBJECT (aiff, "unsupported format given, seek aborted.");
    return FALSE;
  }
}

/*
 * gst_aiff_parse_peek_chunk_info:
 * @aiff AIFFparse object
 * @tag holder for tag
 * @size holder for tag size
 *
 * Peek next chunk info (tag and size)
 *
 * Returns: %TRUE when the chunk info (header) is available
 */
static gboolean
gst_aiff_parse_peek_chunk_info (GstAiffParse * aiff, guint32 * tag,
    guint32 * size)
{
  const guint8 *data = NULL;

  if (gst_adapter_available (aiff->adapter) < 8)
    return FALSE;

  data = gst_adapter_map (aiff->adapter, 8);
  *tag = GST_READ_UINT32_LE (data);
  *size = GST_READ_UINT32_BE (data + 4);
  gst_adapter_unmap (aiff->adapter);

  GST_DEBUG_OBJECT (aiff,
      "Next chunk size is %d bytes, type %" GST_FOURCC_FORMAT, *size,
      GST_FOURCC_ARGS (*tag));

  return TRUE;
}

/*
 * gst_aiff_parse_peek_chunk:
 * @aiff AIFFparse object
 * @tag holder for tag
 * @size holder for tag size
 *
 * Peek enough data for one full chunk
 *
 * Returns: %TRUE when the full chunk is available
 */
static gboolean
gst_aiff_parse_peek_chunk (GstAiffParse * aiff, guint32 * tag, guint32 * size)
{
  guint32 peek_size = 0;
  guint available;

  if (!gst_aiff_parse_peek_chunk_info (aiff, tag, size))
    return FALSE;

  GST_DEBUG_OBJECT (aiff, "Need to peek chunk of %d bytes", *size);
  peek_size = (*size + 1) & ~1;

  available = gst_adapter_available (aiff->adapter);
  if (available >= (8 + peek_size)) {
    return TRUE;
  } else {
    GST_LOG_OBJECT (aiff, "but only %u bytes available now", available);
    return FALSE;
  }
}

static gboolean
gst_aiff_parse_peek_data (GstAiffParse * aiff, guint32 size,
    const guint8 ** data)
{
  if (gst_adapter_available (aiff->adapter) < size)
    return FALSE;

  *data = gst_adapter_map (aiff->adapter, size);
  return TRUE;
}

/*
 * gst_aiff_parse_calculate_duration:
 * @aiff: aiffparse object
 *
 * Calculate duration on demand and store in @aiff.
 *
 * Returns: %TRUE if duration is available.
 */
static gboolean
gst_aiff_parse_calculate_duration (GstAiffParse * aiff)
{
  if (aiff->duration > 0)
    return TRUE;

  if (aiff->datasize > 0 && aiff->bps > 0) {
    aiff->duration =
        gst_util_uint64_scale_ceil (aiff->datasize, GST_SECOND,
        (guint64) aiff->bps);
    GST_INFO_OBJECT (aiff, "Got duration %" GST_TIME_FORMAT,
        GST_TIME_ARGS (aiff->duration));
    return TRUE;
  }
  return FALSE;
}

static void
gst_aiff_parse_ignore_chunk (GstAiffParse * aiff, guint32 tag, guint32 size)
{
  guint flush;

  if (aiff->streaming) {
    if (!gst_aiff_parse_peek_chunk (aiff, &tag, &size))
      return;
  }
  GST_WARNING_OBJECT (aiff, "Ignoring tag %" GST_FOURCC_FORMAT,
      GST_FOURCC_ARGS (tag));
  flush = 8 + ((size + 1) & ~1);
  aiff->offset += flush;
  if (aiff->streaming) {
    gst_adapter_flush (aiff->adapter, flush);
  }
}

static double
gst_aiff_parse_read_IEEE80 (guint8 * buf)
{
  int s = buf[0] & 0xff;
  int e = ((buf[0] & 0x7f) << 8) | (buf[1] & 0xff);
  double f = ((unsigned long) (buf[2] & 0xff) << 24) |
      ((buf[3] & 0xff) << 16) | ((buf[4] & 0xff) << 8) | (buf[5] & 0xff);

  if (e == 32767) {
    if (buf[2] & 0x80)
      return HUGE_VAL;          /* Really NaN, but this won't happen in reality */
    else {
      if (s)
        return -HUGE_VAL;
      else
        return HUGE_VAL;
    }
  }

  f = ldexp (f, 32);
  f += ((buf[6] & 0xff) << 24) |
      ((buf[7] & 0xff) << 16) | ((buf[8] & 0xff) << 8) | (buf[9] & 0xff);

  return ldexp (f, e - 16446);
}

static gboolean
gst_aiff_parse_parse_comm (GstAiffParse * aiff, GstBuffer * buf)
{
  int size;
  GstMapInfo info;
  guint32 fourcc;

  if (!gst_buffer_map (buf, &info, GST_MAP_READ)) {
    GST_WARNING_OBJECT (aiff, "Can't map buffer");
    gst_buffer_unref (buf);
    return FALSE;
  }

  if (aiff->is_aifc)
    size = 22;
  else
    size = 18;

  if (info.size < size)
    goto too_small;

  aiff->channels = GST_READ_UINT16_BE (info.data);
  aiff->total_frames = GST_READ_UINT32_BE (info.data + 2);
  aiff->depth = GST_READ_UINT16_BE (info.data + 6);
  aiff->width = GST_ROUND_UP_8 (aiff->depth);
  aiff->rate = (int) gst_aiff_parse_read_IEEE80 (info.data + 8);

  aiff->floating_point = FALSE;

  if (aiff->is_aifc) {
    fourcc = GST_READ_UINT32_LE (info.data + 18);

    /* We only support the 'trivial' uncompressed AIFC, but it can be
     * either big or little endian */
    switch (fourcc) {
      case GST_MAKE_FOURCC ('N', 'O', 'N', 'E'):
        aiff->endianness = G_BIG_ENDIAN;
        break;
      case GST_MAKE_FOURCC ('s', 'o', 'w', 't'):
        aiff->endianness = G_LITTLE_ENDIAN;
        break;
      case GST_MAKE_FOURCC ('F', 'L', '3', '2'):
      case GST_MAKE_FOURCC ('f', 'l', '3', '2'):
        aiff->floating_point = TRUE;
        aiff->width = aiff->depth = 32;
        aiff->endianness = G_BIG_ENDIAN;
        break;
      case GST_MAKE_FOURCC ('f', 'l', '6', '4'):
        aiff->floating_point = TRUE;
        aiff->width = aiff->depth = 64;
        aiff->endianness = G_BIG_ENDIAN;
        break;
      default:
        goto unknown_compression;
    }
  } else
    aiff->endianness = G_BIG_ENDIAN;

  gst_buffer_unmap (buf, &info);
  gst_buffer_unref (buf);

  return TRUE;

  /* ERRORS */
too_small:
  {
    GST_WARNING_OBJECT (aiff, "COMM chunk too short, cannot parse header");
    gst_buffer_unmap (buf, &info);
    gst_buffer_unref (buf);
    return FALSE;
  }
unknown_compression:
  {
    GST_WARNING_OBJECT (aiff, "Unsupported compression in AIFC "
        "file: %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
    gst_buffer_unmap (buf, &info);
    gst_buffer_unref (buf);
    return FALSE;
  }
}

static GstFlowReturn
gst_aiff_parse_read_chunk (GstAiffParse * aiff, guint64 * offset, guint32 * tag,
    GstBuffer ** data)
{
  guint size;
  GstFlowReturn res;
  GstBuffer *buf = NULL;
  GstMapInfo info;

  if ((res =
          gst_pad_pull_range (aiff->sinkpad, *offset, 8, &buf)) != GST_FLOW_OK)
    return res;

  gst_buffer_map (buf, &info, GST_MAP_READ);
  *tag = GST_READ_UINT32_LE (info.data);
  size = GST_READ_UINT32_BE (info.data + 4);
  gst_buffer_unmap (buf, &info);
  gst_buffer_unref (buf);
  buf = NULL;

  if ((res =
          gst_pad_pull_range (aiff->sinkpad, (*offset) + 8, size,
              &buf)) != GST_FLOW_OK)
    return res;
  else if (gst_buffer_get_size (buf) < size)
    goto too_small;

  *data = buf;
  *offset += 8 + GST_ROUND_UP_2 (size);

  return GST_FLOW_OK;

  /* ERRORS */
too_small:
  {
    /* short read, we return EOS to mark the EOS case */
    GST_DEBUG_OBJECT (aiff,
        "not enough data (available=%" G_GSIZE_FORMAT ", needed=%u)",
        gst_buffer_get_size (buf), size);
    gst_buffer_unref (buf);
    return GST_FLOW_EOS;
  }

}

#define _P(pos) (G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_ ##pos)

static GstCaps *
gst_aiff_parse_create_caps (GstAiffParse * aiff)
{
  GstCaps *caps = NULL;
  const gchar *format = NULL;
  guint64 channel_mask;

  if (aiff->floating_point) {
    if (aiff->endianness == G_BIG_ENDIAN) {
      if (aiff->width == 32)
        format = "F32BE";
      else if (aiff->width == 64)
        format = "F64BE";
    }
  } else {
    if (aiff->endianness == G_BIG_ENDIAN) {
      if (aiff->width == 8)
        format = "S8";
      else if (aiff->width == 16)
        format = "S16BE";
      else if (aiff->width == 24)
        format = "S24BE";
      else if (aiff->width == 32)
        format = "S32BE";
    } else {
      if (aiff->width == 8)
        format = "S8";
      else if (aiff->width == 16)
        format = "S16LE";
      else if (aiff->width == 24)
        format = "S24LE";
      else if (aiff->width == 32)
        format = "S32LE";
    }
  }
  if (format) {
    caps = gst_caps_new_simple ("audio/x-raw",
        "format", G_TYPE_STRING, format,
        "channels", G_TYPE_INT, aiff->channels,
        "layout", G_TYPE_STRING, "interleaved",
        "rate", G_TYPE_INT, aiff->rate, NULL);
  }

  if (aiff->channels > 2) {
    GST_FIXME_OBJECT (aiff, "using fallback channel layout for %d channels",
        aiff->channels);

    /* based on AIFF-1.3.pdf */
    switch (aiff->channels) {
      case 1:
        channel_mask = 0;
        break;
      case 2:
        channel_mask = _P (FRONT_LEFT) | _P (FRONT_RIGHT);
        break;
      case 3:
        channel_mask = _P (FRONT_LEFT) | _P (FRONT_RIGHT) | _P (FRONT_CENTER);
        break;
      case 4:
        /* lists both this and 'quad' but doesn't say how to distinguish the two */
        channel_mask =
            _P (FRONT_LEFT) | _P (FRONT_RIGHT) | _P (REAR_LEFT) |
            _P (REAR_RIGHT);
        break;
      case 6:
        channel_mask =
            _P (FRONT_LEFT) | _P (FRONT_LEFT_OF_CENTER) | _P (FRONT_CENTER) |
            _P (FRONT_RIGHT) | _P (FRONT_RIGHT_OF_CENTER) | _P (LFE1);
        break;
      default:
        channel_mask = gst_audio_channel_get_fallback_mask (aiff->channels);
        break;
    }


    if (channel_mask != 0) {
      gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
          NULL);
    }
  }

  GST_DEBUG_OBJECT (aiff, "Created caps: %" GST_PTR_FORMAT, caps);

  return caps;
}

static GstFlowReturn
gst_aiff_parse_stream_headers (GstAiffParse * aiff)
{
  GstFlowReturn res;
  GstBuffer *buf = NULL;
  guint32 tag, size;
  gboolean gotdata = FALSE;
  gboolean done = FALSE;
  GstEvent **event_p;
  gint64 upstream_size = 0;

  gst_pad_peer_query_duration (aiff->sinkpad, GST_FORMAT_BYTES, &upstream_size);
  GST_DEBUG_OBJECT (aiff, "upstream size %" G_GUINT64_FORMAT, upstream_size);

  /* loop headers until we get data */
  while (!done) {
    if (aiff->streaming) {
      if (!gst_aiff_parse_peek_chunk_info (aiff, &tag, &size))
        return GST_FLOW_OK;
    } else {
      GstMapInfo info;

      if ((res =
              gst_pad_pull_range (aiff->sinkpad, aiff->offset, 8,
                  &buf)) != GST_FLOW_OK)
        goto header_read_error;

      gst_buffer_map (buf, &info, GST_MAP_READ);
      tag = GST_READ_UINT32_LE (info.data);
      size = GST_READ_UINT32_BE (info.data + 4);
      gst_buffer_unmap (buf, &info);
      gst_buffer_unref (buf);
      buf = NULL;
    }

    GST_INFO_OBJECT (aiff,
        "Got TAG: %" GST_FOURCC_FORMAT ", offset %" G_GUINT64_FORMAT,
        GST_FOURCC_ARGS (tag), aiff->offset);

    /* We just keep reading chunks until we find the one we're interested in.
     */
    switch (tag) {
      case GST_MAKE_FOURCC ('C', 'O', 'M', 'M'):{
        GstCaps *caps;
        GstEvent *event;
        gchar *stream_id;

        if (aiff->streaming) {
          if (!gst_aiff_parse_peek_chunk (aiff, &tag, &size))
            return GST_FLOW_OK;

          gst_adapter_flush (aiff->adapter, 8);
          aiff->offset += 8;

          buf = gst_adapter_take_buffer (aiff->adapter, size);
          aiff->offset += size;
        } else {
          if ((res = gst_aiff_parse_read_chunk (aiff,
                      &aiff->offset, &tag, &buf)) != GST_FLOW_OK)
            return res;
        }

        if (!gst_aiff_parse_parse_comm (aiff, buf))
          goto parse_header_error;

        /* do sanity checks of header fields */
        if (aiff->channels == 0)
          goto no_channels;
        if (aiff->rate == 0)
          goto no_rate;

        stream_id =
            gst_pad_create_stream_id (aiff->srcpad, GST_ELEMENT_CAST (aiff),
            NULL);
        event = gst_event_new_stream_start (stream_id);
        gst_event_set_group_id (event, gst_util_group_id_next ());
        gst_pad_push_event (aiff->srcpad, event);
        g_free (stream_id);

        GST_DEBUG_OBJECT (aiff, "creating the caps");

        caps = gst_aiff_parse_create_caps (aiff);
        if (caps == NULL)
          goto unknown_format;

        gst_pad_push_event (aiff->srcpad, gst_event_new_caps (caps));
        gst_caps_unref (caps);

        aiff->bytes_per_sample = aiff->channels * aiff->width / 8;
        aiff->bps = aiff->bytes_per_sample * aiff->rate;

        if (aiff->bytes_per_sample <= 0)
          goto no_bytes_per_sample;

        aiff->got_comm = TRUE;
        break;
      }
      case GST_MAKE_FOURCC ('S', 'S', 'N', 'D'):{
        guint32 datasize;

        GST_DEBUG_OBJECT (aiff, "Got 'SSND' TAG, size : %d", size);

        /* Now, read the 8-byte header in the SSND chunk */
        if (aiff->streaming) {
          const guint8 *ssnddata = NULL;

          if (!gst_aiff_parse_peek_data (aiff, 16, &ssnddata))
            return GST_FLOW_OK;

          aiff->ssnd_offset = GST_READ_UINT32_BE (ssnddata + 8);
          aiff->ssnd_blocksize = GST_READ_UINT32_BE (ssnddata + 12);
          gst_adapter_unmap (aiff->adapter);
          gst_adapter_flush (aiff->adapter, 16);
        } else {
          GstBuffer *ssndbuf = NULL;
          GstMapInfo info;

          if ((res =
                  gst_pad_pull_range (aiff->sinkpad, aiff->offset, 16,
                      &ssndbuf)) != GST_FLOW_OK)
            goto header_read_error;

          gst_buffer_map (ssndbuf, &info, GST_MAP_READ);
          aiff->ssnd_offset = GST_READ_UINT32_BE (info.data + 8);
          aiff->ssnd_blocksize = GST_READ_UINT32_BE (info.data + 12);
          gst_buffer_unmap (ssndbuf, &info);
          gst_buffer_unref (ssndbuf);
        }

        gotdata = TRUE;

        /* 8 byte chunk header, 8 byte SSND header */
        aiff->offset += 16;
        datasize = size - 8;

        aiff->datastart = aiff->offset + aiff->ssnd_offset;
        /* file might be truncated */
        if (upstream_size) {
          size = MIN (datasize, (upstream_size - aiff->datastart));
        }
        aiff->datasize = (guint64) datasize;
        aiff->dataleft = (guint64) datasize;
        aiff->end_offset = datasize + aiff->datastart;
        if (!aiff->streaming) {
          /* We will continue looking at chunks until the end - to read tags,
           * etc. */
          aiff->offset += datasize;
        }
        GST_DEBUG_OBJECT (aiff, "datasize = %d", datasize);
        if (aiff->streaming) {
          done = TRUE;
        }
        break;
      }
      case GST_MAKE_FOURCC ('I', 'D', '3', ' '):{
        GstTagList *tags;

        if (aiff->streaming) {
          if (!gst_aiff_parse_peek_chunk (aiff, &tag, &size))
            return GST_FLOW_OK;

          gst_adapter_flush (aiff->adapter, 8);
          aiff->offset += 8;

          buf = gst_adapter_take_buffer (aiff->adapter, size);
        } else {
          if ((res = gst_aiff_parse_read_chunk (aiff,
                      &aiff->offset, &tag, &buf)) != GST_FLOW_OK)
            return res;
        }

        GST_LOG_OBJECT (aiff, "ID3 chunk of size %" G_GSIZE_FORMAT,
            gst_buffer_get_size (buf));

        tags = gst_tag_list_from_id3v2_tag (buf);
        gst_buffer_unref (buf);

        GST_INFO_OBJECT (aiff, "ID3 tags: %" GST_PTR_FORMAT, tags);

        if (aiff->tags == NULL) {
          aiff->tags = tags;
        } else {
          gst_tag_list_insert (aiff->tags, tags, GST_TAG_MERGE_APPEND);
          gst_tag_list_unref (tags);
        }
        break;
      }
      case GST_MAKE_FOURCC ('C', 'H', 'A', 'N'):{
        GST_FIXME_OBJECT (aiff, "Handle CHAN chunk with channel layouts");
        gst_aiff_parse_ignore_chunk (aiff, tag, size);
        break;
      }
      default:
        gst_aiff_parse_ignore_chunk (aiff, tag, size);
    }

    buf = NULL;

    if (upstream_size && (aiff->offset >= upstream_size)) {
      /* Now we have gone through the whole file */
      done = TRUE;
    }
  }

  /* We read all the chunks (in pull mode) or reached the SSND chunk
   * (in push mode). We must have both COMM and SSND now; error out 
   * otherwise.
   */
  if (!aiff->got_comm) {
    GST_WARNING_OBJECT (aiff, "Failed to find COMM chunk");
    goto no_header;
  }
  if (!gotdata) {
    GST_WARNING_OBJECT (aiff, "Failed to find SSND chunk");
    goto no_data;
  }

  GST_DEBUG_OBJECT (aiff, "Finished parsing headers");

  if (gst_aiff_parse_calculate_duration (aiff)) {
    gst_segment_init (&aiff->segment, GST_FORMAT_TIME);
    aiff->segment.duration = aiff->duration;
  } else {
    /* no bitrate, let downstream peer do the math, we'll feed it bytes. */
    gst_segment_init (&aiff->segment, GST_FORMAT_BYTES);
    aiff->segment.duration = aiff->datasize;
  }

  /* now we have all the info to perform a pending seek if any, if no
   * event, this will still do the right thing and it will also send
   * the right segment event downstream. */
  gst_aiff_parse_perform_seek (aiff, aiff->seek_event, TRUE);
  /* remove pending event */
  event_p = &aiff->seek_event;
  gst_event_replace (event_p, NULL);

  /* we just started, we are discont */
  aiff->discont = TRUE;

  aiff->state = AIFF_PARSE_DATA;

  /* determine reasonable max buffer size,
   * that is, buffers not too small either size or time wise
   * so we do not end up with too many of them */
  /* var abuse */
  upstream_size = 0;
  gst_aiff_parse_time_to_bytepos (aiff, 40 * GST_MSECOND, &upstream_size);
  aiff->max_buf_size = upstream_size;
  aiff->max_buf_size = MAX (aiff->max_buf_size, MAX_BUFFER_SIZE);
  if (aiff->bytes_per_sample > 0)
    aiff->max_buf_size -= (aiff->max_buf_size % aiff->bytes_per_sample);

  GST_DEBUG_OBJECT (aiff, "max buffer size %u", aiff->max_buf_size);

  return GST_FLOW_OK;

  /* ERROR */
no_header:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, TYPE_NOT_FOUND, (NULL),
        ("Invalid AIFF header (no COMM found)"));
    return GST_FLOW_ERROR;
  }
no_data:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, TYPE_NOT_FOUND, (NULL),
        ("Invalid AIFF: no SSND found"));
    return GST_FLOW_ERROR;
  }
parse_header_error:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, DEMUX, (NULL),
        ("Couldn't parse audio header"));
    return GST_FLOW_ERROR;
  }
no_channels:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, FAILED, (NULL),
        ("Stream claims to contain no channels - invalid data"));
    return GST_FLOW_ERROR;
  }
no_rate:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, FAILED, (NULL),
        ("Stream with sample_rate == 0 - invalid data"));
    return GST_FLOW_ERROR;
  }
no_bytes_per_sample:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, FAILED, (NULL),
        ("Could not calculate bytes per sample - invalid data"));
    return GST_FLOW_ERROR;
  }
unknown_format:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, TYPE_NOT_FOUND, (NULL),
        ("No caps found for format 0x%x, %d channels, %d Hz",
            aiff->format, aiff->channels, aiff->rate));
    return GST_FLOW_ERROR;
  }
header_read_error:
  {
    GST_ELEMENT_ERROR (aiff, STREAM, DEMUX, (NULL),
        ("Couldn't read in header"));
    return GST_FLOW_ERROR;
  }
}

/*
 * Read AIFF file tag when streaming
 */
static GstFlowReturn
gst_aiff_parse_parse_stream_init (GstAiffParse * aiff)
{
  if (gst_adapter_available (aiff->adapter) >= 12) {
    GstBuffer *tmp;

    /* _take flushes the data */
    tmp = gst_adapter_take_buffer (aiff->adapter, 12);

    GST_DEBUG_OBJECT (aiff, "Parsing aiff header");
    if (!gst_aiff_parse_parse_file_header (aiff, tmp))
      return GST_FLOW_ERROR;

    aiff->offset += 12;
    /* Go to next state */
    aiff->state = AIFF_PARSE_HEADER;
  }
  return GST_FLOW_OK;
}

/* handle an event sent directly to the element.
 *
 * This event can be sent either in the READY state or the
 * >READY state. The only event of interest really is the seek
 * event.
 *
 * In the READY state we can only store the event and try to
 * respect it when going to PAUSED. We assume we are in the
 * READY state when our parsing state != AIFF_PARSE_DATA.
 *
 * When we are steaming, we can simply perform the seek right
 * away.
 */
static gboolean
gst_aiff_parse_send_event (GstElement * element, GstEvent * event)
{
  GstAiffParse *aiff = GST_AIFF_PARSE (element);
  gboolean res = FALSE;
  GstEvent **event_p;

  GST_DEBUG_OBJECT (aiff, "received event %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      if (aiff->state == AIFF_PARSE_DATA) {
        /* we can handle the seek directly when streaming data */
        res = gst_aiff_parse_perform_seek (aiff, event, FALSE);
      } else {
        GST_DEBUG_OBJECT (aiff, "queuing seek for later");

        event_p = &aiff->seek_event;
        gst_event_replace (event_p, event);

        /* we always return true */
        res = TRUE;
      }
      break;
    default:
      break;
  }
  gst_event_unref (event);
  return res;
}

static GstFlowReturn
gst_aiff_parse_stream_data (GstAiffParse * aiff)
{
  GstBuffer *buf = NULL;
  GstFlowReturn res = GST_FLOW_OK;
  guint64 desired, obtained;
  GstClockTime timestamp, next_timestamp, duration;
  guint64 pos, nextpos;

  if (aiff->bytes_per_sample <= 0) {
    GST_ELEMENT_ERROR (aiff, STREAM, WRONG_TYPE, (NULL),
        ("File is not a valid AIFF file (invalid bytes per sample)"));
    return GST_FLOW_ERROR;
  }

iterate_adapter:
  GST_LOG_OBJECT (aiff,
      "offset: %" G_GINT64_FORMAT " , end: %" G_GINT64_FORMAT " , dataleft: %"
      G_GINT64_FORMAT, aiff->offset, aiff->end_offset, aiff->dataleft);

  /* Get the next n bytes and output them */
  if (aiff->dataleft == 0 || aiff->dataleft < aiff->bytes_per_sample)
    goto found_eos;

  /* scale the amount of data by the segment rate so we get equal
   * amounts of data regardless of the playback rate */
  desired =
      MIN (gst_guint64_to_gdouble (aiff->dataleft),
      aiff->max_buf_size * ABS (aiff->segment.rate));

  if (desired >= aiff->bytes_per_sample)
    desired -= (desired % aiff->bytes_per_sample);

  GST_LOG_OBJECT (aiff, "Fetching %" G_GINT64_FORMAT " bytes of data "
      "from the sinkpad", desired);

  if (aiff->streaming) {
    guint avail = gst_adapter_available (aiff->adapter);

    if (avail < desired) {
      GST_LOG_OBJECT (aiff, "Got only %d bytes of data from the sinkpad",
          avail);
      return GST_FLOW_OK;
    }

    buf = gst_adapter_take_buffer (aiff->adapter, desired);
  } else {
    if ((res = gst_pad_pull_range (aiff->sinkpad, aiff->offset,
                desired, &buf)) != GST_FLOW_OK)
      goto pull_error;
  }

  /* If we have a pending close/start segment, send it now. */
  if (G_UNLIKELY (aiff->close_segment != NULL)) {
    gst_pad_push_event (aiff->srcpad, aiff->close_segment);
    aiff->close_segment = NULL;
  }
  if (G_UNLIKELY (aiff->start_segment != NULL)) {
    gst_pad_push_event (aiff->srcpad, aiff->start_segment);
    aiff->start_segment = NULL;
  }
  if (G_UNLIKELY (aiff->tags != NULL)) {
    gst_pad_push_event (aiff->srcpad, gst_event_new_tag (aiff->tags));
    aiff->tags = NULL;
  }

  obtained = gst_buffer_get_size (buf);

  /* our positions in bytes */
  pos = aiff->offset - aiff->datastart;
  nextpos = pos + obtained;

  /* update offsets, does not overflow. */
  GST_BUFFER_OFFSET (buf) = pos / aiff->bytes_per_sample;
  GST_BUFFER_OFFSET_END (buf) = nextpos / aiff->bytes_per_sample;

  if (aiff->bps > 0) {
    /* and timestamps if we have a bitrate, be careful for overflows */
    timestamp =
        gst_util_uint64_scale_ceil (pos, GST_SECOND, (guint64) aiff->bps);
    next_timestamp =
        gst_util_uint64_scale_ceil (nextpos, GST_SECOND, (guint64) aiff->bps);
    duration = next_timestamp - timestamp;

    /* update current running segment position */
    aiff->segment.position = next_timestamp;
  } else {
    /* no bitrate, all we know is that the first sample has timestamp 0, all
     * other positions and durations have unknown timestamp. */
    if (pos == 0)
      timestamp = 0;
    else
      timestamp = GST_CLOCK_TIME_NONE;
    duration = GST_CLOCK_TIME_NONE;
    /* update current running segment position with byte offset */
    aiff->segment.position = nextpos;
  }
  if (aiff->discont) {
    GST_DEBUG_OBJECT (aiff, "marking DISCONT");
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    aiff->discont = FALSE;
  }

  GST_BUFFER_TIMESTAMP (buf) = timestamp;
  GST_BUFFER_DURATION (buf) = duration;

  GST_LOG_OBJECT (aiff,
      "Got buffer. timestamp:%" GST_TIME_FORMAT " , duration:%" GST_TIME_FORMAT
      ", size:%" G_GUINT64_FORMAT, GST_TIME_ARGS (timestamp),
      GST_TIME_ARGS (duration), obtained);

  if ((res = gst_pad_push (aiff->srcpad, buf)) != GST_FLOW_OK)
    goto push_error;

  if (obtained < aiff->dataleft) {
    aiff->offset += obtained;
    aiff->dataleft -= obtained;
  } else {
    aiff->offset += aiff->dataleft;
    aiff->dataleft = 0;
  }

  /* Iterate until need more data, so adapter size won't grow */
  if (aiff->streaming) {
    GST_LOG_OBJECT (aiff,
        "offset: %" G_GINT64_FORMAT " , end: %" G_GINT64_FORMAT, aiff->offset,
        aiff->end_offset);
    goto iterate_adapter;
  }
  return res;

  /* ERROR */
found_eos:
  {
    GST_DEBUG_OBJECT (aiff, "found EOS");
    return GST_FLOW_EOS;
  }
pull_error:
  {
    /* check if we got EOS */
    if (res == GST_FLOW_EOS)
      goto found_eos;

    GST_WARNING_OBJECT (aiff,
        "Error getting %" G_GINT64_FORMAT " bytes from the "
        "sinkpad (dataleft = %" G_GINT64_FORMAT ")", desired, aiff->dataleft);
    return res;
  }
push_error:
  {
    GST_INFO_OBJECT (aiff,
        "Error pushing on srcpad %s:%s, reason %s, is linked? = %d",
        GST_DEBUG_PAD_NAME (aiff->srcpad), gst_flow_get_name (res),
        gst_pad_is_linked (aiff->srcpad));
    return res;
  }
}

static void
gst_aiff_parse_loop (GstPad * pad)
{
  GstFlowReturn ret;
  GstAiffParse *aiff = GST_AIFF_PARSE (GST_PAD_PARENT (pad));

  GST_LOG_OBJECT (aiff, "process data");

  switch (aiff->state) {
    case AIFF_PARSE_START:
      GST_INFO_OBJECT (aiff, "AIFF_PARSE_START");
      if ((ret = gst_aiff_parse_stream_init (aiff)) != GST_FLOW_OK)
        goto pause;

      aiff->state = AIFF_PARSE_HEADER;
      /* fall-through */

    case AIFF_PARSE_HEADER:
      GST_INFO_OBJECT (aiff, "AIFF_PARSE_HEADER");
      if ((ret = gst_aiff_parse_stream_headers (aiff)) != GST_FLOW_OK)
        goto pause;

      aiff->state = AIFF_PARSE_DATA;
      GST_INFO_OBJECT (aiff, "AIFF_PARSE_DATA");
      /* fall-through */

    case AIFF_PARSE_DATA:
      if ((ret = gst_aiff_parse_stream_data (aiff)) != GST_FLOW_OK)
        goto pause;
      break;
    default:
      g_assert_not_reached ();
  }
  return;

  /* ERRORS */
pause:
  {
    const gchar *reason = gst_flow_get_name (ret);

    GST_DEBUG_OBJECT (aiff, "pausing task, reason %s", reason);
    aiff->segment_running = FALSE;
    gst_pad_pause_task (pad);

    if (ret == GST_FLOW_EOS) {
      /* perform EOS logic */
      if (aiff->segment.flags & GST_SEEK_FLAG_SEGMENT) {
        GstClockTime stop;

        if ((stop = aiff->segment.stop) == -1)
          stop = aiff->segment.duration;

        gst_element_post_message (GST_ELEMENT_CAST (aiff),
            gst_message_new_segment_done (GST_OBJECT_CAST (aiff),
                aiff->segment.format, stop));
        gst_pad_push_event (aiff->srcpad,
            gst_event_new_segment_done (aiff->segment.format, stop));
      } else {
        gst_pad_push_event (aiff->srcpad, gst_event_new_eos ());
      }
    } else if (ret < GST_FLOW_EOS || ret == GST_FLOW_NOT_LINKED) {
      /* for fatal errors we post an error message, post the error
       * first so the app knows about the error first. */
      GST_ELEMENT_ERROR (aiff, STREAM, FAILED,
          (_("Internal data flow error.")),
          ("streaming task paused, reason %s (%d)", reason, ret));
      gst_pad_push_event (aiff->srcpad, gst_event_new_eos ());
    }
    return;
  }
}

static GstFlowReturn
gst_aiff_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn ret;
  GstAiffParse *aiff = GST_AIFF_PARSE (parent);

  GST_LOG_OBJECT (aiff, "adapter_push %" G_GSIZE_FORMAT " bytes",
      gst_buffer_get_size (buf));

  gst_adapter_push (aiff->adapter, buf);

  switch (aiff->state) {
    case AIFF_PARSE_START:
      GST_INFO_OBJECT (aiff, "AIFF_PARSE_START");
      if ((ret = gst_aiff_parse_parse_stream_init (aiff)) != GST_FLOW_OK)
        goto done;

      if (aiff->state != AIFF_PARSE_HEADER)
        break;

      /* otherwise fall-through */
    case AIFF_PARSE_HEADER:
      GST_INFO_OBJECT (aiff, "AIFF_PARSE_HEADER");
      if ((ret = gst_aiff_parse_stream_headers (aiff)) != GST_FLOW_OK)
        goto done;

      if (!aiff->got_comm || aiff->datastart == 0)
        break;

      aiff->state = AIFF_PARSE_DATA;
      GST_INFO_OBJECT (aiff, "AIFF_PARSE_DATA");

      /* fall-through */
    case AIFF_PARSE_DATA:
      if ((ret = gst_aiff_parse_stream_data (aiff)) != GST_FLOW_OK)
        goto done;
      break;
    default:
      g_return_val_if_reached (GST_FLOW_ERROR);
  }
done:
  return ret;
}

static gboolean
gst_aiff_parse_pad_convert (GstPad * pad,
    GstFormat src_format, gint64 src_value,
    GstFormat * dest_format, gint64 * dest_value)
{
  GstAiffParse *aiffparse;
  gboolean res = TRUE;

  aiffparse = GST_AIFF_PARSE (GST_PAD_PARENT (pad));

  if (*dest_format == src_format) {
    *dest_value = src_value;
    return TRUE;
  }

  if (aiffparse->bytes_per_sample <= 0)
    return FALSE;

  GST_INFO_OBJECT (aiffparse, "converting value from %s to %s",
      gst_format_get_name (src_format), gst_format_get_name (*dest_format));

  switch (src_format) {
    case GST_FORMAT_BYTES:
      switch (*dest_format) {
        case GST_FORMAT_DEFAULT:
          *dest_value = src_value / aiffparse->bytes_per_sample;
          break;
        case GST_FORMAT_TIME:
          if (aiffparse->bps > 0) {
            *dest_value = gst_util_uint64_scale_ceil (src_value, GST_SECOND,
                (guint64) aiffparse->bps);
            break;
          }
          /* Else fallthrough */
        default:
          res = FALSE;
          goto done;
      }
      break;

    case GST_FORMAT_DEFAULT:
      switch (*dest_format) {
        case GST_FORMAT_BYTES:
          *dest_value = src_value * aiffparse->bytes_per_sample;
          break;
        case GST_FORMAT_TIME:
          *dest_value = gst_util_uint64_scale (src_value, GST_SECOND,
              (guint64) aiffparse->rate);
          break;
        default:
          res = FALSE;
          goto done;
      }
      break;

    case GST_FORMAT_TIME:
      switch (*dest_format) {
        case GST_FORMAT_BYTES:
          if (aiffparse->bps > 0) {
            *dest_value = gst_util_uint64_scale (src_value,
                (guint64) aiffparse->bps, GST_SECOND);
            break;
          }
          /* Else fallthrough */
          break;
        case GST_FORMAT_DEFAULT:
          *dest_value = gst_util_uint64_scale (src_value,
              (guint64) aiffparse->rate, GST_SECOND);
          break;
        default:
          res = FALSE;
          goto done;
      }
      break;

    default:
      res = FALSE;
      goto done;
  }

done:
  return res;

}

/* handle queries for location and length in requested format */
static gboolean
gst_aiff_parse_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res = FALSE;
  GstAiffParse *aiff = GST_AIFF_PARSE (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
    {
      gint64 duration = 0;
      GstFormat format;

      /* only if we know */
      if (aiff->state != AIFF_PARSE_DATA)
        break;

      gst_query_parse_duration (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_TIME:{
          if ((res = gst_aiff_parse_calculate_duration (aiff))) {
            duration = aiff->duration;
          }
          break;
        }
        default:
          format = GST_FORMAT_BYTES;
          duration = aiff->datasize;
          break;
      }
      gst_query_set_duration (query, format, duration);
      break;
    }
    case GST_QUERY_CONVERT:
    {
      gint64 srcvalue, dstvalue;
      GstFormat srcformat, dstformat;

      /* only if we know */
      if (aiff->state != AIFF_PARSE_DATA)
        break;

      gst_query_parse_convert (query, &srcformat, &srcvalue,
          &dstformat, &dstvalue);
      res = gst_aiff_parse_pad_convert (pad, srcformat, srcvalue,
          &dstformat, &dstvalue);
      if (res)
        gst_query_set_convert (query, srcformat, srcvalue, dstformat, dstvalue);
      break;
    }
    case GST_QUERY_SEEKING:{
      GstFormat fmt;

      /* only if we know */
      if (aiff->state != AIFF_PARSE_DATA)
        break;

      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
      if (fmt == GST_FORMAT_TIME) {
        gboolean seekable = TRUE;

        if (!gst_aiff_parse_calculate_duration (aiff)) {
          seekable = FALSE;
        }
        gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
            0, aiff->duration);
        res = TRUE;
      }
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
  return res;
}

static gboolean
gst_aiff_parse_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstAiffParse *aiffparse = GST_AIFF_PARSE (parent);
  gboolean res = FALSE;

  GST_DEBUG_OBJECT (aiffparse, "%s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      /* can only handle events when we are in the data state */
      if (aiffparse->state == AIFF_PARSE_DATA) {
        res = gst_aiff_parse_perform_seek (aiffparse, event, FALSE);
      }
      gst_event_unref (event);
      break;
    default:
      res = gst_pad_push_event (aiffparse->sinkpad, event);
      break;
  }
  return res;
}

static gboolean
gst_aiff_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
{
  GstQuery *query;
  gboolean pull_mode;

  query = gst_query_new_scheduling ();

  if (!gst_pad_peer_query (sinkpad, query)) {
    gst_query_unref (query);
    goto activate_push;
  }

  pull_mode = gst_query_has_scheduling_mode_with_flags (query,
      GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
  gst_query_unref (query);

  if (!pull_mode)
    goto activate_push;

  GST_DEBUG_OBJECT (sinkpad, "going to pull mode");
  return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);

activate_push:
  {
    GST_DEBUG_OBJECT (sinkpad, "going to push (streaming) mode");
    return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
  }
}


static gboolean
gst_aiff_parse_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;
  GstAiffParse *aiff = GST_AIFF_PARSE (parent);

  if (aiff->adapter) {
    g_object_unref (aiff->adapter);
    aiff->adapter = NULL;
  }

  switch (mode) {
    case GST_PAD_MODE_PUSH:
      if (active) {
        aiff->streaming = TRUE;
        aiff->adapter = gst_adapter_new ();
      }
      res = TRUE;
      break;
    case GST_PAD_MODE_PULL:
      if (active) {
        aiff->streaming = FALSE;
        aiff->adapter = NULL;
        aiff->segment_running = TRUE;
        res =
            gst_pad_start_task (sinkpad, (GstTaskFunction) gst_aiff_parse_loop,
            sinkpad, NULL);
      } else {
        aiff->segment_running = FALSE;
        res = gst_pad_stop_task (sinkpad);
      }
      break;
    default:
      res = FALSE;
      break;
  }
  return res;
};

static GstFlowReturn
gst_aiff_parse_flush_data (GstAiffParse * aiff)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint av;

  if ((av = gst_adapter_available (aiff->adapter)) > 0) {
    aiff->dataleft = av;
    aiff->end_offset = aiff->offset + av;
    ret = gst_aiff_parse_stream_data (aiff);
  }

  return ret;
}


static gboolean
gst_aiff_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstAiffParse *aiff = GST_AIFF_PARSE (parent);
  gboolean ret = TRUE;

  GST_DEBUG_OBJECT (aiff, "handling %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      /* discard, we'll come up with proper src caps */
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      gint64 start, stop, offset = 0, end_offset = -1;
      GstSegment segment;

      /* some debug output */
      gst_event_copy_segment (event, &segment);
      GST_DEBUG_OBJECT (aiff, "received segment %" GST_SEGMENT_FORMAT,
          &segment);

      /* now we are either committed to TIME or BYTE format,
       * and we only expect a BYTE segment, e.g. following a seek */
      if (segment.format == GST_FORMAT_BYTES) {
        /* handle (un)signed issues */
        start = segment.start;
        stop = segment.stop;
        if (start > 0) {
          offset = start;
          start -= aiff->datastart;
          start = MAX (start, 0);
        }
        if (stop > 0) {
          end_offset = stop;
          stop -= aiff->datastart;
          stop = MAX (stop, 0);
        }
        if (aiff->state == AIFF_PARSE_DATA &&
            aiff->segment.format == GST_FORMAT_TIME) {
          /* operating in format TIME, so we can convert */
          if (aiff->bps) {
            if (start >= 0)
              start =
                  gst_util_uint64_scale_ceil (start, GST_SECOND,
                  (guint64) aiff->bps);
            if (stop >= 0)
              stop =
                  gst_util_uint64_scale_ceil (stop, GST_SECOND,
                  (guint64) aiff->bps);
          } else {
            GST_DEBUG_OBJECT (aiff, "unable to compute segment start/stop");
            goto exit;
          }
        }
      } else {
        GST_DEBUG_OBJECT (aiff, "unsupported segment format, ignoring");
        goto exit;
      }

      segment.start = start;
      segment.stop = stop;

      /* accept upstream's notion of segment and distribute along */
      if (aiff->state == AIFF_PARSE_DATA) {
        segment.format = aiff->segment.format;
        segment.time = segment.position = segment.start;
        segment.duration = aiff->segment.duration;
      }

      gst_segment_copy_into (&segment, &aiff->segment);

      if (aiff->start_segment)
        gst_event_unref (aiff->start_segment);

      aiff->start_segment = gst_event_new_segment (&segment);

      /* stream leftover data in current segment */
      if (aiff->state == AIFF_PARSE_DATA)
        gst_aiff_parse_flush_data (aiff);
      /* and set up streaming thread for next one */
      aiff->offset = offset;
      aiff->end_offset = end_offset;
      if (aiff->end_offset > 0) {
        aiff->dataleft = aiff->end_offset - aiff->offset;
      } else {
        /* infinity; upstream will EOS when done */
        aiff->dataleft = G_MAXUINT64;
      }
    exit:
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_FLUSH_START:
      ret = gst_pad_push_event (aiff->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      ret = gst_pad_push_event (aiff->srcpad, event);
      gst_adapter_clear (aiff->adapter);
      break;
    default:
      ret = gst_pad_event_default (aiff->sinkpad, parent, event);
      break;
  }

  return ret;
}

static GstStateChangeReturn
gst_aiff_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstAiffParse *aiff = GST_AIFF_PARSE (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_aiff_parse_reset (aiff);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_aiff_parse_reset (aiff);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }
  return ret;
}
