/* GStreamer
 * Copyright (C) 2009 Igalia S.L.
 * Author: Iago Toral Quiroga <itoral@igalia.com>
 * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
 * Copyright (C) 2011 Nokia Corporation. All rights reserved.
 *   Contact: Stefan Kost <stefan.kost@nokia.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:gstaudiodecoder
 * @short_description: Base class for audio decoders
 * @see_also: #GstBaseTransform
 *
 * This base class is for audio decoders turning encoded data into
 * raw audio samples.
 *
 * GstAudioDecoder and subclass should cooperate as follows.
 * <orderedlist>
 * <listitem>
 *   <itemizedlist><title>Configuration</title>
 *   <listitem><para>
 *     Initially, GstAudioDecoder calls @start when the decoder element
 *     is activated, which allows subclass to perform any global setup.
 *     Base class (context) parameters can already be set according to subclass
 *     capabilities (or possibly upon receive more information in subsequent
 *     @set_format).
 *   </para></listitem>
 *   <listitem><para>
 *     GstAudioDecoder calls @set_format to inform subclass of the format
 *     of input audio data that it is about to receive.
 *     While unlikely, it might be called more than once, if changing input
 *     parameters require reconfiguration.
 *   </para></listitem>
 *   <listitem><para>
 *     GstAudioDecoder calls @stop at end of all processing.
 *   </para></listitem>
 *   </itemizedlist>
 * </listitem>
 * As of configuration stage, and throughout processing, GstAudioDecoder
 * provides various (context) parameters, e.g. describing the format of
 * output audio data (valid when output caps have been set) or current parsing state.
 * Conversely, subclass can and should configure context to inform
 * base class of its expectation w.r.t. buffer handling.
 * <listitem>
 *   <itemizedlist>
 *   <title>Data processing</title>
 *     <listitem><para>
 *       Base class gathers input data, and optionally allows subclass
 *       to parse this into subsequently manageable (as defined by subclass)
 *       chunks.  Such chunks are subsequently referred to as 'frames',
 *       though they may or may not correspond to 1 (or more) audio format frame.
 *     </para></listitem>
 *     <listitem><para>
 *       Input frame is provided to subclass' @handle_frame.
 *     </para></listitem>
 *     <listitem><para>
 *       If codec processing results in decoded data, subclass should call
 *       @gst_audio_decoder_finish_frame to have decoded data pushed
 *       downstream.
 *     </para></listitem>
 *     <listitem><para>
 *       Just prior to actually pushing a buffer downstream,
 *       it is passed to @pre_push.  Subclass should either use this callback
 *       to arrange for additional downstream pushing or otherwise ensure such
 *       custom pushing occurs after at least a method call has finished since
 *       setting src pad caps.
 *     </para></listitem>
 *     <listitem><para>
 *       During the parsing process GstAudioDecoderClass will handle both
 *       srcpad and sinkpad events. Sink events will be passed to subclass
 *       if @event callback has been provided.
 *     </para></listitem>
 *   </itemizedlist>
 * </listitem>
 * <listitem>
 *   <itemizedlist><title>Shutdown phase</title>
 *   <listitem><para>
 *     GstAudioDecoder class calls @stop to inform the subclass that data
 *     parsing will be stopped.
 *   </para></listitem>
 *   </itemizedlist>
 * </listitem>
 * </orderedlist>
 *
 * Subclass is responsible for providing pad template caps for
 * source and sink pads. The pads need to be named "sink" and "src". It also
 * needs to set the fixed caps on srcpad, when the format is ensured.  This
 * is typically when base class calls subclass' @set_format function, though
 * it might be delayed until calling @gst_audio_decoder_finish_frame.
 *
 * In summary, above process should have subclass concentrating on
 * codec data processing while leaving other matters to base class,
 * such as most notably timestamp handling.  While it may exert more control
 * in this area (see e.g. @pre_push), it is very much not recommended.
 *
 * In particular, base class will try to arrange for perfect output timestamps
 * as much as possible while tracking upstream timestamps.
 * To this end, if deviation between the next ideal expected perfect timestamp
 * and upstream exceeds #GstAudioDecoder:tolerance, then resync to upstream
 * occurs (which would happen always if the tolerance mechanism is disabled).
 *
 * In non-live pipelines, baseclass can also (configurably) arrange for
 * output buffer aggregation which may help to redue large(r) numbers of
 * small(er) buffers being pushed and processed downstream.
 *
 * On the other hand, it should be noted that baseclass only provides limited
 * seeking support (upon explicit subclass request), as full-fledged support
 * should rather be left to upstream demuxer, parser or alike.  This simple
 * approach caters for seeking and duration reporting using estimated input
 * bitrates.
 *
 * Things that subclass need to take care of:
 * <itemizedlist>
 *   <listitem><para>Provide pad templates</para></listitem>
 *   <listitem><para>
 *      Set source pad caps when appropriate
 *   </para></listitem>
 *   <listitem><para>
 *      Set user-configurable properties to sane defaults for format and
 *      implementing codec at hand, and convey some subclass capabilities and
 *      expectations in context.
 *   </para></listitem>
 *   <listitem><para>
 *      Accept data in @handle_frame and provide encoded results to
 *      @gst_audio_decoder_finish_frame.  If it is prepared to perform
 *      PLC, it should also accept NULL data in @handle_frame and provide for
 *      data for indicated duration.
 *   </para></listitem>
 * </itemizedlist>
 */

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

#include "gstaudiodecoder.h"
#include <gst/pbutils/descriptions.h>

#include <string.h>

GST_DEBUG_CATEGORY (audiodecoder_debug);
#define GST_CAT_DEFAULT audiodecoder_debug

#define GST_AUDIO_DECODER_GET_PRIVATE(obj)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_DECODER, \
        GstAudioDecoderPrivate))

enum
{
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_LATENCY,
  PROP_TOLERANCE,
  PROP_PLC
};

#define DEFAULT_LATENCY    0
#define DEFAULT_TOLERANCE  0
#define DEFAULT_PLC        FALSE
#define DEFAULT_DRAINABLE  TRUE
#define DEFAULT_NEEDS_FORMAT  FALSE

typedef struct _GstAudioDecoderContext
{
  /* last negotiated input caps */
  GstCaps *input_caps;

  /* (output) audio format */
  GstAudioInfo info;
  gboolean output_format_changed;

  /* parsing state */
  gboolean eos;
  gboolean sync;

  gboolean had_output_data;
  gboolean had_input_data;

  /* misc */
  gint delay;

  /* output */
  gboolean do_plc;
  gboolean do_estimate_rate;
  gint max_errors;
  /* MT-protected (with LOCK) */
  GstClockTime min_latency;
  GstClockTime max_latency;

  GstAllocator *allocator;
  GstAllocationParams params;
} GstAudioDecoderContext;

struct _GstAudioDecoderPrivate
{
  /* activation status */
  gboolean active;

  /* input base/first ts as basis for output ts */
  GstClockTime base_ts;
  /* input samples processed and sent downstream so far (w.r.t. base_ts) */
  guint64 samples;

  /* collected input data */
  GstAdapter *adapter;
  /* tracking input ts for changes */
  GstClockTime prev_ts;
  guint64 prev_distance;
  /* frames obtained from input */
  GQueue frames;
  /* collected output data */
  GstAdapter *adapter_out;
  /* ts and duration for output data collected above */
  GstClockTime out_ts, out_dur;
  /* mark outgoing discont */
  gboolean discont;

  /* subclass gave all it could already */
  gboolean drained;
  /* subclass currently being forcibly drained */
  gboolean force;
  /* need to handle changed input caps */
  gboolean do_caps;

  /* input bps estimatation */
  /* global in bytes seen */
  guint64 bytes_in;
  /* global samples sent out */
  guint64 samples_out;
  /* bytes flushed during parsing */
  guint sync_flush;
  /* error count */
  gint error_count;
  /* codec id tag */
  GstTagList *taglist;
  gboolean taglist_changed;

  /* whether circumstances allow output aggregation */
  gint agg;

  /* reverse playback queues */
  /* collect input */
  GList *gather;
  /* to-be-decoded */
  GList *decode;
  /* reversed output */
  GList *queued;

  /* context storage */
  GstAudioDecoderContext ctx;

  /* properties */
  GstClockTime latency;
  GstClockTime tolerance;
  gboolean plc;
  gboolean drainable;
  gboolean needs_format;

  /* pending serialized sink events, will be sent from finish_frame() */
  GList *pending_events;
};

//* Default channel layouts taken from audioconvert */
static const GstAudioChannelPosition default_positions[8][8] = {
  /* 1 channel */
  {
        GST_AUDIO_CHANNEL_POSITION_MONO,
      },
  /* 2 channels */
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
      },
  /* 3 channels (2.1) */
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_LFE1,
      },
  /* 4 channels (4.0) */
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
      },
  /* 5 channels */
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
      },
  /* 6 channels (5.1) */
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_LFE1,
      },
  /* 7 channels (6.1) */
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_LFE1,
        GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
      },
  /* 8 channels (7.1) */
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_LFE1,
        GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
        GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
      }
};

static void gst_audio_decoder_finalize (GObject * object);
static void gst_audio_decoder_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_audio_decoder_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

static void gst_audio_decoder_clear_queues (GstAudioDecoder * dec);
static GstFlowReturn gst_audio_decoder_chain_reverse (GstAudioDecoder *
    dec, GstBuffer * buf);

static GstStateChangeReturn gst_audio_decoder_change_state (GstElement *
    element, GstStateChange transition);
static gboolean gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec,
    GstEvent * event);
static gboolean gst_audio_decoder_src_eventfunc (GstAudioDecoder * dec,
    GstEvent * event);
static gboolean gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_audio_decoder_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec,
    GstCaps * caps);
static GstFlowReturn gst_audio_decoder_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static gboolean gst_audio_decoder_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static void gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full);

static gboolean gst_audio_decoder_decide_allocation_default (GstAudioDecoder *
    dec, GstQuery * query);
static gboolean gst_audio_decoder_propose_allocation_default (GstAudioDecoder *
    dec, GstQuery * query);
static gboolean gst_audio_decoder_negotiate_default (GstAudioDecoder * dec);
static gboolean gst_audio_decoder_negotiate_unlocked (GstAudioDecoder * dec);

static GstElementClass *parent_class = NULL;

static void gst_audio_decoder_class_init (GstAudioDecoderClass * klass);
static void gst_audio_decoder_init (GstAudioDecoder * dec,
    GstAudioDecoderClass * klass);

GType
gst_audio_decoder_get_type (void)
{
  static volatile gsize audio_decoder_type = 0;

  if (g_once_init_enter (&audio_decoder_type)) {
    GType _type;
    static const GTypeInfo audio_decoder_info = {
      sizeof (GstAudioDecoderClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_audio_decoder_class_init,
      NULL,
      NULL,
      sizeof (GstAudioDecoder),
      0,
      (GInstanceInitFunc) gst_audio_decoder_init,
    };

    _type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstAudioDecoder", &audio_decoder_info, G_TYPE_FLAG_ABSTRACT);
    g_once_init_leave (&audio_decoder_type, _type);
  }
  return audio_decoder_type;
}


static void
gst_audio_decoder_class_init (GstAudioDecoderClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstAudioDecoderClass *audiodecoder_class;

  gobject_class = G_OBJECT_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);
  audiodecoder_class = GST_AUDIO_DECODER_CLASS (klass);

  parent_class = g_type_class_peek_parent (klass);

  g_type_class_add_private (klass, sizeof (GstAudioDecoderPrivate));

  GST_DEBUG_CATEGORY_INIT (audiodecoder_debug, "audiodecoder", 0,
      "audio decoder base class");

  gobject_class->set_property = gst_audio_decoder_set_property;
  gobject_class->get_property = gst_audio_decoder_get_property;
  gobject_class->finalize = gst_audio_decoder_finalize;

  element_class->change_state =
      GST_DEBUG_FUNCPTR (gst_audio_decoder_change_state);

  /* Properties */
  g_object_class_install_property (gobject_class, PROP_LATENCY,
      g_param_spec_int64 ("min-latency", "Minimum Latency",
          "Aggregate output data to a minimum of latency time (ns)",
          0, G_MAXINT64, DEFAULT_LATENCY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_TOLERANCE,
      g_param_spec_int64 ("tolerance", "Tolerance",
          "Perfect ts while timestamp jitter/imperfection within tolerance (ns)",
          0, G_MAXINT64, DEFAULT_TOLERANCE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PLC,
      g_param_spec_boolean ("plc", "Packet Loss Concealment",
          "Perform packet loss concealment (if supported)",
          DEFAULT_PLC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  audiodecoder_class->sink_event =
      GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_eventfunc);
  audiodecoder_class->src_event =
      GST_DEBUG_FUNCPTR (gst_audio_decoder_src_eventfunc);
  audiodecoder_class->propose_allocation =
      GST_DEBUG_FUNCPTR (gst_audio_decoder_propose_allocation_default);
  audiodecoder_class->decide_allocation =
      GST_DEBUG_FUNCPTR (gst_audio_decoder_decide_allocation_default);
  audiodecoder_class->negotiate =
      GST_DEBUG_FUNCPTR (gst_audio_decoder_negotiate_default);
}

static void
gst_audio_decoder_init (GstAudioDecoder * dec, GstAudioDecoderClass * klass)
{
  GstPadTemplate *pad_template;

  GST_DEBUG_OBJECT (dec, "gst_audio_decoder_init");

  dec->priv = GST_AUDIO_DECODER_GET_PRIVATE (dec);

  /* Setup sink pad */
  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
  g_return_if_fail (pad_template != NULL);

  dec->sinkpad = gst_pad_new_from_template (pad_template, "sink");
  gst_pad_set_event_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_event));
  gst_pad_set_chain_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (gst_audio_decoder_chain));
  gst_pad_set_query_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_query));
  gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
  GST_DEBUG_OBJECT (dec, "sinkpad created");

  /* Setup source pad */
  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
  g_return_if_fail (pad_template != NULL);

  dec->srcpad = gst_pad_new_from_template (pad_template, "src");
  gst_pad_set_event_function (dec->srcpad,
      GST_DEBUG_FUNCPTR (gst_audio_decoder_src_event));
  gst_pad_set_query_function (dec->srcpad,
      GST_DEBUG_FUNCPTR (gst_audio_decoder_src_query));
  gst_pad_use_fixed_caps (dec->srcpad);
  gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
  GST_DEBUG_OBJECT (dec, "srcpad created");

  dec->priv->adapter = gst_adapter_new ();
  dec->priv->adapter_out = gst_adapter_new ();
  g_queue_init (&dec->priv->frames);

  g_rec_mutex_init (&dec->stream_lock);

  /* property default */
  dec->priv->latency = DEFAULT_LATENCY;
  dec->priv->tolerance = DEFAULT_TOLERANCE;
  dec->priv->plc = DEFAULT_PLC;
  dec->priv->drainable = DEFAULT_DRAINABLE;
  dec->priv->needs_format = DEFAULT_NEEDS_FORMAT;

  /* init state */
  gst_audio_decoder_reset (dec, TRUE);
  GST_DEBUG_OBJECT (dec, "init ok");
}

static void
gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full)
{
  GST_DEBUG_OBJECT (dec, "gst_audio_decoder_reset");

  GST_AUDIO_DECODER_STREAM_LOCK (dec);

  if (full) {
    dec->priv->active = FALSE;
    dec->priv->bytes_in = 0;
    dec->priv->samples_out = 0;
    dec->priv->agg = -1;
    dec->priv->error_count = 0;
    gst_audio_decoder_clear_queues (dec);

    if (dec->priv->taglist) {
      gst_tag_list_unref (dec->priv->taglist);
      dec->priv->taglist = NULL;
    }
    dec->priv->taglist_changed = FALSE;

    gst_segment_init (&dec->input_segment, GST_FORMAT_TIME);
    gst_segment_init (&dec->output_segment, GST_FORMAT_TIME);

    g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL);
    g_list_free (dec->priv->pending_events);
    dec->priv->pending_events = NULL;

    if (dec->priv->ctx.allocator)
      gst_object_unref (dec->priv->ctx.allocator);

    gst_caps_replace (&dec->priv->ctx.input_caps, NULL);

    memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));

    gst_audio_info_init (&dec->priv->ctx.info);
    dec->priv->ctx.max_errors = GST_AUDIO_DECODER_MAX_ERRORS;
    dec->priv->ctx.had_output_data = FALSE;
    dec->priv->ctx.had_input_data = FALSE;
  }

  g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
  g_queue_clear (&dec->priv->frames);
  gst_adapter_clear (dec->priv->adapter);
  gst_adapter_clear (dec->priv->adapter_out);
  dec->priv->out_ts = GST_CLOCK_TIME_NONE;
  dec->priv->out_dur = 0;
  dec->priv->prev_ts = GST_CLOCK_TIME_NONE;
  dec->priv->prev_distance = 0;
  dec->priv->drained = TRUE;
  dec->priv->base_ts = GST_CLOCK_TIME_NONE;
  dec->priv->samples = 0;
  dec->priv->discont = TRUE;
  dec->priv->sync_flush = FALSE;

  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
}

static void
gst_audio_decoder_finalize (GObject * object)
{
  GstAudioDecoder *dec;

  g_return_if_fail (GST_IS_AUDIO_DECODER (object));
  dec = GST_AUDIO_DECODER (object);

  if (dec->priv->adapter) {
    g_object_unref (dec->priv->adapter);
  }
  if (dec->priv->adapter_out) {
    g_object_unref (dec->priv->adapter_out);
  }

  g_rec_mutex_clear (&dec->stream_lock);

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

static gboolean
gst_audio_decoder_push_event (GstAudioDecoder * dec, GstEvent * event)
{
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:{
      GstSegment seg;

      GST_AUDIO_DECODER_STREAM_LOCK (dec);
      gst_event_copy_segment (event, &seg);

      GST_DEBUG_OBJECT (dec, "starting segment %" GST_SEGMENT_FORMAT, &seg);

      dec->output_segment = seg;
      GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
      break;
    }
    default:
      break;
  }

  return gst_pad_push_event (dec->srcpad, event);
}

static gboolean
gst_audio_decoder_negotiate_default (GstAudioDecoder * dec)
{
  GstAudioDecoderClass *klass;
  gboolean res = TRUE;
  GstCaps *caps;
  GstCaps *prevcaps;
  GstQuery *query = NULL;
  GstAllocator *allocator;
  GstAllocationParams params;

  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);
  g_return_val_if_fail (GST_AUDIO_INFO_IS_VALID (&dec->priv->ctx.info), FALSE);

  klass = GST_AUDIO_DECODER_GET_CLASS (dec);

  caps = gst_audio_info_to_caps (&dec->priv->ctx.info);

  GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);

  if (dec->priv->pending_events) {
    GList **pending_events, *l;

    pending_events = &dec->priv->pending_events;

    GST_DEBUG_OBJECT (dec, "Pushing pending events");
    for (l = *pending_events; l;) {
      GstEvent *event = GST_EVENT (l->data);
      GList *tmp;

      if (GST_EVENT_TYPE (event) < GST_EVENT_CAPS) {
        gst_audio_decoder_push_event (dec, l->data);
        tmp = l;
        l = l->next;
        *pending_events = g_list_delete_link (*pending_events, tmp);
      } else {
        l = l->next;
      }
    }
  }

  prevcaps = gst_pad_get_current_caps (dec->srcpad);
  if (!prevcaps || !gst_caps_is_equal (prevcaps, caps))
    res = gst_pad_set_caps (dec->srcpad, caps);
  if (prevcaps)
    gst_caps_unref (prevcaps);

  if (!res)
    goto done;
  dec->priv->ctx.output_format_changed = FALSE;

  query = gst_query_new_allocation (caps, TRUE);
  if (!gst_pad_peer_query (dec->srcpad, query)) {
    GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints");
  }

  g_assert (klass->decide_allocation != NULL);
  res = klass->decide_allocation (dec, query);

  GST_DEBUG_OBJECT (dec, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, res,
      query);

  if (!res)
    goto no_decide_allocation;

  /* we got configuration from our peer or the decide_allocation method,
   * parse them */
  if (gst_query_get_n_allocation_params (query) > 0) {
    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
  } else {
    allocator = NULL;
    gst_allocation_params_init (&params);
  }

  if (dec->priv->ctx.allocator)
    gst_object_unref (dec->priv->ctx.allocator);
  dec->priv->ctx.allocator = allocator;
  dec->priv->ctx.params = params;

done:

  if (query)
    gst_query_unref (query);
  gst_caps_unref (caps);

  return res;

  /* ERRORS */
no_decide_allocation:
  {
    GST_WARNING_OBJECT (dec, "Subclass failed to decide allocation");
    goto done;
  }
}

static gboolean
gst_audio_decoder_negotiate_unlocked (GstAudioDecoder * dec)
{
  GstAudioDecoderClass *klass = GST_AUDIO_DECODER_GET_CLASS (dec);
  gboolean ret = TRUE;

  if (G_LIKELY (klass->negotiate))
    ret = klass->negotiate (dec);

  return ret;
}

/**
 * gst_audio_decoder_negotiate:
 * @dec: a #GstAudioDecoder
 *
 * Negotiate with downstream elements to currently configured #GstAudioInfo.
 * Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
 * negotiate fails.
 *
 * Returns: #TRUE if the negotiation succeeded, else #FALSE.
 */
gboolean
gst_audio_decoder_negotiate (GstAudioDecoder * dec)
{
  GstAudioDecoderClass *klass;
  gboolean res = TRUE;

  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);

  klass = GST_AUDIO_DECODER_GET_CLASS (dec);

  GST_AUDIO_DECODER_STREAM_LOCK (dec);
  gst_pad_check_reconfigure (dec->srcpad);
  if (klass->negotiate) {
    res = klass->negotiate (dec);
    if (!res)
      gst_pad_mark_reconfigure (dec->srcpad);
  }
  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

  return res;
}

/**
 * gst_audio_decoder_set_output_format:
 * @dec: a #GstAudioDecoder
 * @info: #GstAudioInfo
 *
 * Configure output info on the srcpad of @dec.
 *
 * Returns: %TRUE on success.
 **/
gboolean
gst_audio_decoder_set_output_format (GstAudioDecoder * dec,
    const GstAudioInfo * info)
{
  gboolean res = TRUE;
  guint old_rate;
  GstCaps *caps = NULL;
  GstCaps *templ_caps;

  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);
  g_return_val_if_fail (GST_AUDIO_INFO_IS_VALID (info), FALSE);

  GST_DEBUG_OBJECT (dec, "Setting output format");

  GST_AUDIO_DECODER_STREAM_LOCK (dec);

  /* If the audio info can't be converted to caps,
   * it was invalid */
  caps = gst_audio_info_to_caps (info);
  if (!caps)
    goto refuse_caps;

  /* Only allow caps that are a subset of the template caps */
  templ_caps = gst_pad_get_pad_template_caps (dec->srcpad);
  if (!gst_caps_is_subset (caps, templ_caps)) {
    GST_WARNING_OBJECT (dec, "Requested output format %" GST_PTR_FORMAT
        " do not match template %" GST_PTR_FORMAT, caps, templ_caps);
    gst_caps_unref (templ_caps);
    goto refuse_caps;
  }
  gst_caps_unref (templ_caps);

  /* adjust ts tracking to new sample rate */
  old_rate = GST_AUDIO_INFO_RATE (&dec->priv->ctx.info);
  if (GST_CLOCK_TIME_IS_VALID (dec->priv->base_ts) && old_rate) {
    dec->priv->base_ts +=
        GST_FRAMES_TO_CLOCK_TIME (dec->priv->samples, old_rate);
    dec->priv->samples = 0;
  }

  /* copy the GstAudioInfo */
  dec->priv->ctx.info = *info;
  dec->priv->ctx.output_format_changed = TRUE;

done:
  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

  if (caps)
    gst_caps_unref (caps);

  return res;

  /* ERRORS */
refuse_caps:
  {
    GST_WARNING_OBJECT (dec, "invalid output format");
    res = FALSE;
    goto done;
  }
}

static gboolean
gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec, GstCaps * caps)
{
  GstAudioDecoderClass *klass;
  gboolean res = TRUE;

  klass = GST_AUDIO_DECODER_GET_CLASS (dec);

  GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);

  GST_AUDIO_DECODER_STREAM_LOCK (dec);

  if (dec->priv->ctx.input_caps
      && gst_caps_is_equal (dec->priv->ctx.input_caps, caps)) {
    GST_DEBUG_OBJECT (dec, "Caps did not change, not setting again");
    goto done;
  }

  /* NOTE pbutils only needed here */
  /* TODO maybe (only) upstream demuxer/parser etc should handle this ? */
#if 0
  if (!dec->priv->taglist)
    dec->priv->taglist = gst_tag_list_new ();
  dec->priv->taglist = gst_tag_list_make_writable (dec->priv->taglist);
  gst_pb_utils_add_codec_description_to_tag_list (dec->priv->taglist,
      GST_TAG_AUDIO_CODEC, caps);
  dec->priv->taglist_changed = TRUE;
#endif

  if (klass->set_format)
    res = klass->set_format (dec, caps);

  if (res)
    gst_caps_replace (&dec->priv->ctx.input_caps, caps);

done:
  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

  return res;
}

static void
gst_audio_decoder_setup (GstAudioDecoder * dec)
{
  GstQuery *query;
  gboolean res;

  /* check if in live pipeline, then latency messing is no-no */
  query = gst_query_new_latency ();
  res = gst_pad_peer_query (dec->sinkpad, query);
  if (res) {
    gst_query_parse_latency (query, &res, NULL, NULL);
    res = !res;
  }
  gst_query_unref (query);

  /* normalize to bool */
  dec->priv->agg = ! !res;
}

static GstFlowReturn
gst_audio_decoder_push_forward (GstAudioDecoder * dec, GstBuffer * buf)
{
  GstAudioDecoderClass *klass;
  GstAudioDecoderPrivate *priv;
  GstAudioDecoderContext *ctx;
  GstFlowReturn ret = GST_FLOW_OK;

  klass = GST_AUDIO_DECODER_GET_CLASS (dec);
  priv = dec->priv;
  ctx = &dec->priv->ctx;

  g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR);

  if (G_UNLIKELY (!buf)) {
    g_assert_not_reached ();
    return GST_FLOW_OK;
  }

  ctx->had_output_data = TRUE;

  GST_LOG_OBJECT (dec,
      "clipping buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
      ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));

  /* clip buffer */
  buf = gst_audio_buffer_clip (buf, &dec->output_segment, ctx->info.rate,
      ctx->info.bpf);
  if (G_UNLIKELY (!buf)) {
    GST_DEBUG_OBJECT (dec, "no data after clipping to segment");
    goto exit;
  }

  /* decorate */
  if (G_UNLIKELY (priv->discont)) {
    GST_LOG_OBJECT (dec, "marking discont");
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    priv->discont = FALSE;
  }

  /* track where we are */
  if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
    /* duration should always be valid for raw audio */
    g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
    dec->output_segment.position =
        GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
  }

  if (klass->pre_push) {
    /* last chance for subclass to do some dirty stuff */
    ret = klass->pre_push (dec, &buf);
    if (ret != GST_FLOW_OK || !buf) {
      GST_DEBUG_OBJECT (dec, "subclass returned %s, buf %p",
          gst_flow_get_name (ret), buf);
      if (buf)
        gst_buffer_unref (buf);
      goto exit;
    }
  }

  GST_LOG_OBJECT (dec,
      "pushing buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
      ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));

  ret = gst_pad_push (dec->srcpad, buf);

exit:
  return ret;
}

/* mini aggregator combining output buffers into fewer larger ones,
 * if so allowed/configured */
static GstFlowReturn
gst_audio_decoder_output (GstAudioDecoder * dec, GstBuffer * buf)
{
  GstAudioDecoderPrivate *priv;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *inbuf = NULL;

  priv = dec->priv;

  if (G_UNLIKELY (priv->agg < 0))
    gst_audio_decoder_setup (dec);

  if (G_LIKELY (buf)) {
    GST_LOG_OBJECT (dec,
        "output buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
        ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
  }

again:
  inbuf = NULL;
  if (priv->agg && dec->priv->latency > 0) {
    gint av;
    gboolean assemble = FALSE;
    const GstClockTimeDiff tol = 10 * GST_MSECOND;
    GstClockTimeDiff diff = -100 * GST_MSECOND;

    av = gst_adapter_available (priv->adapter_out);
    if (G_UNLIKELY (!buf)) {
      /* forcibly send current */
      assemble = TRUE;
      GST_LOG_OBJECT (dec, "forcing fragment flush");
    } else if (av && (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) ||
            !GST_CLOCK_TIME_IS_VALID (priv->out_ts) ||
            ((diff = GST_CLOCK_DIFF (GST_BUFFER_TIMESTAMP (buf),
                        priv->out_ts + priv->out_dur)) > tol) || diff < -tol)) {
      assemble = TRUE;
      GST_LOG_OBJECT (dec, "buffer %d ms apart from current fragment",
          (gint) (diff / GST_MSECOND));
    } else {
      /* add or start collecting */
      if (!av) {
        GST_LOG_OBJECT (dec, "starting new fragment");
        priv->out_ts = GST_BUFFER_TIMESTAMP (buf);
      } else {
        GST_LOG_OBJECT (dec, "adding to fragment");
      }
      gst_adapter_push (priv->adapter_out, buf);
      priv->out_dur += GST_BUFFER_DURATION (buf);
      av += gst_buffer_get_size (buf);
      buf = NULL;
    }
    if (priv->out_dur > dec->priv->latency)
      assemble = TRUE;
    if (av && assemble) {
      GST_LOG_OBJECT (dec, "assembling fragment");
      inbuf = buf;
      buf = gst_adapter_take_buffer (priv->adapter_out, av);
      GST_BUFFER_TIMESTAMP (buf) = priv->out_ts;
      GST_BUFFER_DURATION (buf) = priv->out_dur;
      priv->out_ts = GST_CLOCK_TIME_NONE;
      priv->out_dur = 0;
    }
  }

  if (G_LIKELY (buf)) {
    if (dec->output_segment.rate > 0.0) {
      ret = gst_audio_decoder_push_forward (dec, buf);
      GST_LOG_OBJECT (dec, "buffer pushed: %s", gst_flow_get_name (ret));
    } else {
      ret = GST_FLOW_OK;
      priv->queued = g_list_prepend (priv->queued, buf);
      GST_LOG_OBJECT (dec, "buffer queued");
    }

    if (inbuf) {
      buf = inbuf;
      goto again;
    }
  }

  return ret;
}

static void
send_pending_events (GstAudioDecoder * dec)
{
  GstAudioDecoderPrivate *priv = dec->priv;
  GList *pending_events, *l;

  pending_events = priv->pending_events;
  priv->pending_events = NULL;

  GST_DEBUG_OBJECT (dec, "Pushing pending events");
  for (l = pending_events; l; l = l->next)
    gst_audio_decoder_push_event (dec, l->data);
  g_list_free (pending_events);
}

static GstFlowReturn
check_pending_reconfigure (GstAudioDecoder * dec)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstAudioDecoderContext *ctx;
  gboolean needs_reconfigure;

  ctx = &dec->priv->ctx;

  needs_reconfigure = gst_pad_check_reconfigure (dec->srcpad);
  if (G_UNLIKELY (ctx->output_format_changed ||
          (GST_AUDIO_INFO_IS_VALID (&ctx->info)
              && needs_reconfigure))) {
    if (!gst_audio_decoder_negotiate_unlocked (dec)) {
      gst_pad_mark_reconfigure (dec->srcpad);
      if (GST_PAD_IS_FLUSHING (dec->srcpad))
        ret = GST_FLOW_FLUSHING;
      else
        ret = GST_FLOW_NOT_NEGOTIATED;
    }
  }
  return ret;
}


/**
 * gst_audio_decoder_finish_frame:
 * @dec: a #GstAudioDecoder
 * @buf: decoded data
 * @frames: number of decoded frames represented by decoded data
 *
 * Collects decoded data and pushes it downstream.
 *
 * @buf may be NULL in which case the indicated number of frames
 * are discarded and considered to have produced no output
 * (e.g. lead-in or setup frames).
 * Otherwise, source pad caps must be set when it is called with valid
 * data in @buf.
 *
 * Note that a frame received in gst_audio_decoder_handle_frame() may be
 * invalidated by a call to this function.
 *
 * Returns: a #GstFlowReturn that should be escalated to caller (of caller)
 */
GstFlowReturn
gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf,
    gint frames)
{
  GstAudioDecoderPrivate *priv;
  GstAudioDecoderContext *ctx;
  gint samples = 0;
  GstClockTime ts, next_ts;
  gsize size;
  GstFlowReturn ret = GST_FLOW_OK;

  /* subclass should not hand us no data */
  g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
      GST_FLOW_ERROR);
  /* no dummy calls please */
  g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);

  priv = dec->priv;
  ctx = &dec->priv->ctx;
  size = buf ? gst_buffer_get_size (buf) : 0;

  /* must know the output format by now */
  g_return_val_if_fail (buf == NULL || GST_AUDIO_INFO_IS_VALID (&ctx->info),
      GST_FLOW_ERROR);

  GST_LOG_OBJECT (dec,
      "accepting %" G_GSIZE_FORMAT " bytes == %" G_GSIZE_FORMAT
      " samples for %d frames", buf ? size : -1,
      buf ? size / ctx->info.bpf : -1, frames);

  GST_AUDIO_DECODER_STREAM_LOCK (dec);

  if (buf) {
    ret = check_pending_reconfigure (dec);
    if (ret == GST_FLOW_FLUSHING || ret == GST_FLOW_NOT_NEGOTIATED)
      goto exit;

    if (priv->pending_events)
      send_pending_events (dec);
  }

  /* output shoud be whole number of sample frames */
  if (G_LIKELY (buf && ctx->info.bpf)) {
    if (size % ctx->info.bpf)
      goto wrong_buffer;
    /* per channel least */
    samples = size / ctx->info.bpf;
  }

  /* frame and ts book-keeping */
  if (G_UNLIKELY (frames < 0)) {
    if (G_UNLIKELY (-frames - 1 > priv->frames.length))
      goto overflow;
    frames = priv->frames.length + frames + 1;
  } else if (G_UNLIKELY (frames > priv->frames.length)) {
    if (G_LIKELY (!priv->force)) {
      /* no way we can let this pass */
      g_assert_not_reached ();
      /* really no way */
      goto overflow;
    }
  }

  if (G_LIKELY (priv->frames.length))
    ts = GST_BUFFER_TIMESTAMP (priv->frames.head->data);
  else
    ts = GST_CLOCK_TIME_NONE;

  GST_DEBUG_OBJECT (dec, "leading frame ts %" GST_TIME_FORMAT,
      GST_TIME_ARGS (ts));

  while (priv->frames.length && frames) {
    gst_buffer_unref (g_queue_pop_head (&priv->frames));
    dec->priv->ctx.delay = dec->priv->frames.length;
    frames--;
  }

  if (G_UNLIKELY (!buf))
    goto exit;

  /* lock on */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
    priv->base_ts = ts;
    GST_DEBUG_OBJECT (dec, "base_ts now %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
  }

  /* still no valid ts, track the segment one */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (priv->base_ts)) &&
      dec->output_segment.rate > 0.0) {
    priv->base_ts = dec->output_segment.start;
  }

  /* slightly convoluted approach caters for perfect ts if subclass desires */
  if (GST_CLOCK_TIME_IS_VALID (ts)) {
    if (dec->priv->tolerance > 0) {
      GstClockTimeDiff diff;

      g_assert (GST_CLOCK_TIME_IS_VALID (priv->base_ts));
      next_ts = priv->base_ts +
          gst_util_uint64_scale (priv->samples, GST_SECOND, ctx->info.rate);
      GST_LOG_OBJECT (dec,
          "buffer is %" G_GUINT64_FORMAT " samples past base_ts %"
          GST_TIME_FORMAT ", expected ts %" GST_TIME_FORMAT, priv->samples,
          GST_TIME_ARGS (priv->base_ts), GST_TIME_ARGS (next_ts));
      diff = GST_CLOCK_DIFF (next_ts, ts);
      GST_LOG_OBJECT (dec, "ts diff %d ms", (gint) (diff / GST_MSECOND));
      /* if within tolerance,
       * discard buffer ts and carry on producing perfect stream,
       * otherwise resync to ts */
      if (G_UNLIKELY (diff < (gint64) - dec->priv->tolerance ||
              diff > (gint64) dec->priv->tolerance)) {
        GST_DEBUG_OBJECT (dec, "base_ts resync");
        priv->base_ts = ts;
        priv->samples = 0;
      }
    } else {
      GST_DEBUG_OBJECT (dec, "base_ts resync");
      priv->base_ts = ts;
      priv->samples = 0;
    }
  }

  /* delayed one-shot stuff until confirmed data */
  if (priv->taglist && priv->taglist_changed) {
    GST_DEBUG_OBJECT (dec, "codec tag %" GST_PTR_FORMAT, priv->taglist);
    if (!gst_tag_list_is_empty (priv->taglist))
      gst_audio_decoder_push_event (dec,
          gst_event_new_tag (gst_tag_list_ref (priv->taglist)));
    priv->taglist_changed = FALSE;
  }

  buf = gst_buffer_make_writable (buf);
  if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
    GST_BUFFER_TIMESTAMP (buf) =
        priv->base_ts +
        GST_FRAMES_TO_CLOCK_TIME (priv->samples, ctx->info.rate);
    GST_BUFFER_DURATION (buf) = priv->base_ts +
        GST_FRAMES_TO_CLOCK_TIME (priv->samples + samples, ctx->info.rate) -
        GST_BUFFER_TIMESTAMP (buf);
  } else {
    GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
    GST_BUFFER_DURATION (buf) =
        GST_FRAMES_TO_CLOCK_TIME (samples, ctx->info.rate);
  }
  priv->samples += samples;
  priv->samples_out += samples;

  /* we got data, so note things are looking up */
  if (G_UNLIKELY (dec->priv->error_count))
    dec->priv->error_count = 0;

  ret = gst_audio_decoder_output (dec, buf);

exit:

  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

  return ret;

  /* ERRORS */
wrong_buffer:
  {
    GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL),
        ("buffer size %" G_GSIZE_FORMAT " not a multiple of %d", size,
            ctx->info.bpf));
    gst_buffer_unref (buf);
    ret = GST_FLOW_ERROR;
    goto exit;
  }
overflow:
  {
    GST_ELEMENT_ERROR (dec, STREAM, ENCODE,
        ("received more decoded frames %d than provided %d", frames,
            priv->frames.length), (NULL));
    if (buf)
      gst_buffer_unref (buf);
    ret = GST_FLOW_ERROR;
    goto exit;
  }
}

static GstFlowReturn
gst_audio_decoder_handle_frame (GstAudioDecoder * dec,
    GstAudioDecoderClass * klass, GstBuffer * buffer)
{
  if (G_LIKELY (buffer)) {
    gsize size = gst_buffer_get_size (buffer);
    /* keep around for admin */
    GST_LOG_OBJECT (dec,
        "tracking frame size %" G_GSIZE_FORMAT ", ts %" GST_TIME_FORMAT, size,
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
    g_queue_push_tail (&dec->priv->frames, buffer);
    dec->priv->ctx.delay = dec->priv->frames.length;
    dec->priv->bytes_in += size;
  } else {
    GST_LOG_OBJECT (dec, "providing subclass with NULL frame");
  }

  return klass->handle_frame (dec, buffer);
}

/* maybe subclass configurable instead, but this allows for a whole lot of
 * raw samples, so at least quite some encoded ... */
#define GST_AUDIO_DECODER_MAX_SYNC     10 * 8 * 2 * 1024

static GstFlowReturn
gst_audio_decoder_push_buffers (GstAudioDecoder * dec, gboolean force)
{
  GstAudioDecoderClass *klass;
  GstAudioDecoderPrivate *priv;
  GstAudioDecoderContext *ctx;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *buffer;
  gint av, flush;

  klass = GST_AUDIO_DECODER_GET_CLASS (dec);
  priv = dec->priv;
  ctx = &dec->priv->ctx;

  g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);

  av = gst_adapter_available (priv->adapter);
  GST_DEBUG_OBJECT (dec, "available: %d", av);

  while (ret == GST_FLOW_OK) {

    flush = 0;
    ctx->eos = force;

    if (G_LIKELY (av)) {
      gint len;
      GstClockTime ts;
      guint64 distance;

      /* parse if needed */
      if (klass->parse) {
        gint offset = 0;

        /* limited (legacy) parsing; avoid whole of baseparse */
        GST_DEBUG_OBJECT (dec, "parsing available: %d", av);
        /* piggyback sync state on discont */
        ctx->sync = !priv->discont;
        ret = klass->parse (dec, priv->adapter, &offset, &len);

        g_assert (offset <= av);
        if (offset) {
          /* jumped a bit */
          GST_DEBUG_OBJECT (dec, "skipped %d; setting DISCONT", offset);
          gst_adapter_flush (priv->adapter, offset);
          flush = offset;
          /* avoid parsing indefinitely */
          priv->sync_flush += offset;
          if (priv->sync_flush > GST_AUDIO_DECODER_MAX_SYNC)
            goto parse_failed;
        }

        if (ret == GST_FLOW_EOS) {
          GST_LOG_OBJECT (dec, "no frame yet");
          ret = GST_FLOW_OK;
          break;
        } else if (ret == GST_FLOW_OK) {
          GST_LOG_OBJECT (dec, "frame at offset %d of length %d", offset, len);
          g_assert (len);
          g_assert (offset + len <= av);
          priv->sync_flush = 0;
        } else {
          break;
        }
      } else {
        len = av;
      }
      /* track upstream ts, but do not get stuck if nothing new upstream */
      ts = gst_adapter_prev_pts (priv->adapter, &distance);
      if (ts != priv->prev_ts || distance <= priv->prev_distance) {
        priv->prev_ts = ts;
        priv->prev_distance = distance;
      } else {
        GST_LOG_OBJECT (dec, "ts == prev_ts; discarding");
        ts = GST_CLOCK_TIME_NONE;
      }
      buffer = gst_adapter_take_buffer (priv->adapter, len);
      buffer = gst_buffer_make_writable (buffer);
      GST_BUFFER_TIMESTAMP (buffer) = ts;
      flush += len;
      priv->force = FALSE;
    } else {
      if (!force)
        break;
      if (!priv->drainable) {
        priv->drained = TRUE;
        break;
      }
      buffer = NULL;
      priv->force = TRUE;
    }

    ret = gst_audio_decoder_handle_frame (dec, klass, buffer);

    /* do not keep pushing it ... */
    if (G_UNLIKELY (!av)) {
      priv->drained = TRUE;
      break;
    }

    av -= flush;
    g_assert (av >= 0);
  }

  GST_LOG_OBJECT (dec, "done pushing to subclass");
  return ret;

  /* ERRORS */
parse_failed:
  {
    GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("failed to parse stream"));
    return GST_FLOW_ERROR;
  }
}

static GstFlowReturn
gst_audio_decoder_drain (GstAudioDecoder * dec)
{
  GstFlowReturn ret;

  if (dec->priv->drained && !dec->priv->gather)
    return GST_FLOW_OK;
  else {
    /* dispatch reverse pending buffers */
    /* chain eventually calls upon drain as well, but by that time
     * gather list should be clear, so ok ... */
    if (dec->output_segment.rate < 0.0 && dec->priv->gather)
      gst_audio_decoder_chain_reverse (dec, NULL);
    /* have subclass give all it can */
    ret = gst_audio_decoder_push_buffers (dec, TRUE);
    /* ensure all output sent */
    ret = gst_audio_decoder_output (dec, NULL);
    /* everything should be away now */
    if (dec->priv->frames.length) {
      /* not fatal/impossible though if subclass/codec eats stuff */
      GST_WARNING_OBJECT (dec, "still %d frames left after draining",
          dec->priv->frames.length);
      g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
      g_queue_clear (&dec->priv->frames);
    }
    /* discard (unparsed) leftover */
    gst_adapter_clear (dec->priv->adapter);

    return ret;
  }
}

/* hard == FLUSH, otherwise discont */
static GstFlowReturn
gst_audio_decoder_flush (GstAudioDecoder * dec, gboolean hard)
{
  GstAudioDecoderClass *klass;
  GstFlowReturn ret = GST_FLOW_OK;

  klass = GST_AUDIO_DECODER_GET_CLASS (dec);

  GST_LOG_OBJECT (dec, "flush hard %d", hard);

  if (!hard) {
    ret = gst_audio_decoder_drain (dec);
  } else {
    gst_audio_decoder_clear_queues (dec);
    gst_segment_init (&dec->input_segment, GST_FORMAT_TIME);
    gst_segment_init (&dec->output_segment, GST_FORMAT_TIME);
    dec->priv->error_count = 0;
  }
  /* only bother subclass with flushing if known it is already alive
   * and kicking out stuff */
  if (klass->flush && dec->priv->samples_out > 0)
    klass->flush (dec, hard);
  /* and get (re)set for the sequel */
  gst_audio_decoder_reset (dec, FALSE);

  return ret;
}

static GstFlowReturn
gst_audio_decoder_chain_forward (GstAudioDecoder * dec, GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;

  /* discard silly case, though maybe ts may be of value ?? */
  if (G_UNLIKELY (gst_buffer_get_size (buffer) == 0)) {
    GST_DEBUG_OBJECT (dec, "discarding empty buffer");
    gst_buffer_unref (buffer);
    goto exit;
  }

  /* grab buffer */
  gst_adapter_push (dec->priv->adapter, buffer);
  buffer = NULL;
  /* new stuff, so we can push subclass again */
  dec->priv->drained = FALSE;

  /* hand to subclass */
  ret = gst_audio_decoder_push_buffers (dec, FALSE);

exit:
  GST_LOG_OBJECT (dec, "chain-done");
  return ret;
}

static void
gst_audio_decoder_clear_queues (GstAudioDecoder * dec)
{
  GstAudioDecoderPrivate *priv = dec->priv;

  g_list_foreach (priv->queued, (GFunc) gst_mini_object_unref, NULL);
  g_list_free (priv->queued);
  priv->queued = NULL;
  g_list_foreach (priv->gather, (GFunc) gst_mini_object_unref, NULL);
  g_list_free (priv->gather);
  priv->gather = NULL;
  g_list_foreach (priv->decode, (GFunc) gst_mini_object_unref, NULL);
  g_list_free (priv->decode);
  priv->decode = NULL;
}

/*
 * Input:
 *  Buffer decoding order:  7  8  9  4  5  6  3  1  2  EOS
 *  Discont flag:           D        D        D  D
 *
 * - Each Discont marks a discont in the decoding order.
 *
 * for vorbis, each buffer is a keyframe when we have the previous
 * buffer. This means that to decode buffer 7, we need buffer 6, which
 * arrives out of order.
 *
 * we first gather buffers in the gather queue until we get a DISCONT. We
 * prepend each incomming buffer so that they are in reversed order.
 *
 *    gather queue:    9  8  7
 *    decode queue:
 *    output queue:
 *
 * When a DISCONT is received (buffer 4), we move the gather queue to the
 * decode queue. This is simply done be taking the head of the gather queue
 * and prepending it to the decode queue. This yields:
 *
 *    gather queue:
 *    decode queue:    7  8  9
 *    output queue:
 *
 * Then we decode each buffer in the decode queue in order and put the output
 * buffer in the output queue. The first buffer (7) will not produce any output
 * because it needs the previous buffer (6) which did not arrive yet. This
 * yields:
 *
 *    gather queue:
 *    decode queue:    7  8  9
 *    output queue:    9  8
 *
 * Then we remove the consumed buffers from the decode queue. Buffer 7 is not
 * completely consumed, we need to keep it around for when we receive buffer
 * 6. This yields:
 *
 *    gather queue:
 *    decode queue:    7
 *    output queue:    9  8
 *
 * Then we accumulate more buffers:
 *
 *    gather queue:    6  5  4
 *    decode queue:    7
 *    output queue:
 *
 * prepending to the decode queue on DISCONT yields:
 *
 *    gather queue:
 *    decode queue:    4  5  6  7
 *    output queue:
 *
 * after decoding and keeping buffer 4:
 *
 *    gather queue:
 *    decode queue:    4
 *    output queue:    7  6  5
 *
 * Etc..
 */
static GstFlowReturn
gst_audio_decoder_flush_decode (GstAudioDecoder * dec)
{
  GstAudioDecoderPrivate *priv = dec->priv;
  GstFlowReturn res = GST_FLOW_OK;
  GstClockTime timestamp;
  GList *walk;

  walk = priv->decode;

  GST_DEBUG_OBJECT (dec, "flushing buffers to decoder");

  /* clear buffer and decoder state */
  gst_audio_decoder_flush (dec, FALSE);

  while (walk) {
    GList *next;
    GstBuffer *buf = GST_BUFFER_CAST (walk->data);

    GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
        buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));

    next = g_list_next (walk);
    /* decode buffer, resulting data prepended to output queue */
    gst_buffer_ref (buf);
    res = gst_audio_decoder_chain_forward (dec, buf);

    /* if we generated output, we can discard the buffer, else we
     * keep it in the queue */
    if (priv->queued) {
      GST_DEBUG_OBJECT (dec, "decoded buffer to %p", priv->queued->data);
      priv->decode = g_list_delete_link (priv->decode, walk);
      gst_buffer_unref (buf);
    } else {
      GST_DEBUG_OBJECT (dec, "buffer did not decode, keeping");
    }
    walk = next;
  }

  /* drain any aggregation (or otherwise) leftover */
  gst_audio_decoder_drain (dec);

  /* now send queued data downstream */
  timestamp = GST_CLOCK_TIME_NONE;
  while (priv->queued) {
    GstBuffer *buf = GST_BUFFER_CAST (priv->queued->data);
    GstClockTime duration;

    duration = GST_BUFFER_DURATION (buf);

    /* duration should always be valid for raw audio */
    g_assert (GST_CLOCK_TIME_IS_VALID (duration));

    /* interpolate (backward) if needed */
    if (G_LIKELY (timestamp != -1)) {
      if (timestamp > duration)
        timestamp -= duration;
      else
        timestamp = 0;
    }

    if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
      GST_LOG_OBJECT (dec, "applying reverse interpolated ts %"
          GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
      GST_BUFFER_TIMESTAMP (buf) = timestamp;
    } else {
      /* track otherwise */
      timestamp = GST_BUFFER_TIMESTAMP (buf);
      GST_LOG_OBJECT (dec, "tracking ts %" GST_TIME_FORMAT,
          GST_TIME_ARGS (timestamp));
    }

    if (G_LIKELY (res == GST_FLOW_OK)) {
      GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %" G_GSIZE_FORMAT ", "
          "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
          gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
          GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
      /* should be already, but let's be sure */
      buf = gst_buffer_make_writable (buf);
      /* avoid stray DISCONT from forward processing,
       * which have no meaning in reverse pushing */
      GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
      res = gst_audio_decoder_push_forward (dec, buf);
    } else {
      gst_buffer_unref (buf);
    }

    priv->queued = g_list_delete_link (priv->queued, priv->queued);
  }

  return res;
}

static GstFlowReturn
gst_audio_decoder_chain_reverse (GstAudioDecoder * dec, GstBuffer * buf)
{
  GstAudioDecoderPrivate *priv = dec->priv;
  GstFlowReturn result = GST_FLOW_OK;

  /* if we have a discont, move buffers to the decode list */
  if (!buf || GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
    GST_DEBUG_OBJECT (dec, "received discont");
    while (priv->gather) {
      GstBuffer *gbuf;

      gbuf = GST_BUFFER_CAST (priv->gather->data);
      /* remove from the gather list */
      priv->gather = g_list_delete_link (priv->gather, priv->gather);
      /* copy to decode queue */
      priv->decode = g_list_prepend (priv->decode, gbuf);
    }
    /* decode stuff in the decode queue */
    gst_audio_decoder_flush_decode (dec);
  }

  if (G_LIKELY (buf)) {
    GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %" G_GSIZE_FORMAT ", "
        "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
        gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));

    /* add buffer to gather queue */
    priv->gather = g_list_prepend (priv->gather, buf);
  }

  return result;
}

static gboolean
gst_audio_decoder_do_caps (GstAudioDecoder * dec)
{
  GstCaps *caps = gst_pad_get_current_caps (dec->sinkpad);
  if (caps) {
    if (!gst_audio_decoder_sink_setcaps (dec, caps)) {
      gst_caps_unref (caps);
      return FALSE;
    }
    gst_caps_unref (caps);
  }
  dec->priv->do_caps = FALSE;
  return TRUE;
}

static GstFlowReturn
gst_audio_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstAudioDecoder *dec;
  GstFlowReturn ret;

  dec = GST_AUDIO_DECODER (parent);

  if (G_UNLIKELY (dec->priv->do_caps)) {
    if (!gst_audio_decoder_do_caps (dec)) {
      goto not_negotiated;
    }
  }

  if (G_UNLIKELY (!gst_pad_has_current_caps (pad) && dec->priv->needs_format))
    goto not_negotiated;

  GST_LOG_OBJECT (dec,
      "received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
      ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));

  GST_AUDIO_DECODER_STREAM_LOCK (dec);

  dec->priv->ctx.had_input_data = TRUE;

  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
    gint64 samples, ts;

    /* track present position */
    ts = dec->priv->base_ts;
    samples = dec->priv->samples;

    GST_DEBUG_OBJECT (dec, "handling discont");
    gst_audio_decoder_flush (dec, FALSE);
    dec->priv->discont = TRUE;

    /* buffer may claim DISCONT loudly, if it can't tell us where we are now,
     * we'll stick to where we were ...
     * Particularly useful/needed for upstream BYTE based */
    if (dec->input_segment.rate > 0.0
        && !GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
      GST_DEBUG_OBJECT (dec, "... but restoring previous ts tracking");
      dec->priv->base_ts = ts;
      dec->priv->samples = samples;
    }
  }

  if (dec->input_segment.rate > 0.0)
    ret = gst_audio_decoder_chain_forward (dec, buffer);
  else
    ret = gst_audio_decoder_chain_reverse (dec, buffer);

  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

  return ret;

  /* ERRORS */
not_negotiated:
  {
    GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
        ("decoder not initialized"));
    gst_buffer_unref (buffer);
    return GST_FLOW_NOT_NEGOTIATED;
  }
}

/* perform upstream byte <-> time conversion (duration, seeking)
 * if subclass allows and if enough data for moderately decent conversion */
static inline gboolean
gst_audio_decoder_do_byte (GstAudioDecoder * dec)
{
  return dec->priv->ctx.do_estimate_rate && dec->priv->ctx.info.bpf &&
      dec->priv->ctx.info.rate <= dec->priv->samples_out;
}

/* Must be called holding the GST_AUDIO_DECODER_STREAM_LOCK */
static gboolean
gst_audio_decoder_negotiate_default_caps (GstAudioDecoder * dec)
{
  GstCaps *caps;
  gint i;
  gint channels = 0;
  gint rate;
  guint64 channel_mask = 0;
  gint caps_size;
  GstStructure *structure;

  caps = gst_pad_get_current_caps (dec->srcpad);
  if (caps && !gst_audio_info_from_caps (&dec->priv->ctx.info, caps))
    goto caps_error;
  if (caps)
    gst_caps_unref (caps);

  caps = gst_pad_get_allowed_caps (dec->srcpad);
  if (!caps || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
    goto caps_error;

  /* before fixating, try to use whatever upstream provided */
  caps = gst_caps_make_writable (caps);
  caps_size = gst_caps_get_size (caps);
  if (dec->priv->ctx.input_caps) {
    GstCaps *sinkcaps = dec->priv->ctx.input_caps;
    GstStructure *structure = gst_caps_get_structure (sinkcaps, 0);

    if (gst_structure_get_int (structure, "rate", &rate)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i), "rate",
            G_TYPE_INT, rate, NULL);
      }
    }

    if (gst_structure_get_int (structure, "channels", &channels)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i), "channels",
            G_TYPE_INT, channels, NULL);
      }
    }

    if (gst_structure_get (structure, "channel-mask", GST_TYPE_BITMASK,
            &channel_mask, NULL)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i), "channel-mask",
            GST_TYPE_BITMASK, channel_mask, NULL);
      }
    }
  }

  for (i = 0; i < caps_size; i++) {
    structure = gst_caps_get_structure (caps, i);
    gst_structure_fixate_field_nearest_int (structure,
        "channels", GST_AUDIO_DEF_CHANNELS);
    gst_structure_fixate_field_nearest_int (structure,
        "rate", GST_AUDIO_DEF_RATE);
  }
  caps = gst_caps_fixate (caps);
  structure = gst_caps_get_structure (caps, 0);

  /* Need to add a channel-mask if channels > 2 */
  gst_structure_get_int (structure, "channels", &channels);
  if (channels > 2 && !gst_structure_has_field (structure, "channel-mask")) {
    if (channels <= 8) {
      channel_mask = 0;
      for (i = 0; i < channels; i++)
        channel_mask |=
            G_GUINT64_CONSTANT (1) << default_positions[channels - 1][i];

      gst_structure_set (structure, "channel-mask",
          GST_TYPE_BITMASK, channel_mask, NULL);
    } else {
      GST_WARNING_OBJECT (dec, "No default channel-mask for %d channels",
          channels);
    }
  }

  if (!caps || !gst_audio_info_from_caps (&dec->priv->ctx.info, caps))
    goto caps_error;

  GST_INFO_OBJECT (dec,
      "Chose default caps %" GST_PTR_FORMAT " for initial gap", caps);
  gst_caps_unref (caps);

  if (!gst_audio_decoder_negotiate_unlocked (dec)) {
    GST_INFO_OBJECT (dec, "Failed to negotiate default caps for initial gap");
    gst_pad_mark_reconfigure (dec->srcpad);
    return FALSE;
  }

  return TRUE;

caps_error:
  {
    if (caps)
      gst_caps_unref (caps);
    return FALSE;
  }
}

static gboolean
gst_audio_decoder_handle_gap (GstAudioDecoder * dec, GstEvent * event)
{
  gboolean ret;
  GstClockTime timestamp, duration;

  /* Check if there is a caps pending to be pushed */
  if (G_UNLIKELY (dec->priv->do_caps)) {
    if (!gst_audio_decoder_do_caps (dec)) {
      goto not_negotiated;
    }
  }

  /* Ensure we have caps first */
  GST_AUDIO_DECODER_STREAM_LOCK (dec);
  if (!GST_AUDIO_INFO_IS_VALID (&dec->priv->ctx.info)) {
    if (!gst_audio_decoder_negotiate_default_caps (dec)) {
      GST_ELEMENT_ERROR (dec, STREAM, FORMAT, (NULL),
          ("Decoder output not negotiated before GAP event."));
      GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
      return FALSE;
    }
  }
  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

  gst_event_parse_gap (event, &timestamp, &duration);

  /* time progressed without data, see if we can fill the gap with
   * some concealment data */
  GST_DEBUG_OBJECT (dec,
      "gap event: plc %d, do_plc %d, position %" GST_TIME_FORMAT
      " duration %" GST_TIME_FORMAT,
      dec->priv->plc, dec->priv->ctx.do_plc,
      GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));

  if (dec->priv->plc && dec->priv->ctx.do_plc && dec->input_segment.rate > 0.0) {
    GstAudioDecoderClass *klass = GST_AUDIO_DECODER_GET_CLASS (dec);
    GstBuffer *buf;

    /* hand subclass empty frame with duration that needs covering */
    buf = gst_buffer_new ();
    GST_BUFFER_TIMESTAMP (buf) = timestamp;
    GST_BUFFER_DURATION (buf) = duration;
    /* best effort, not much error handling */
    gst_audio_decoder_handle_frame (dec, klass, buf);
    ret = TRUE;
    gst_event_unref (event);
  } else {
    GstFlowReturn flowret;

    /* sub-class doesn't know how to handle empty buffers,
     * so just try sending GAP downstream */
    flowret = check_pending_reconfigure (dec);
    if (flowret == GST_FLOW_OK) {
      send_pending_events (dec);
      ret = gst_audio_decoder_push_event (dec, event);
    } else {
      ret = FALSE;
    }
  }
  return ret;

  /* ERRORS */
not_negotiated:
  {
    GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
        ("decoder not initialized"));
    return FALSE;
  }
}

static gboolean
gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
{
  gboolean ret;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_STREAM_START:
      GST_AUDIO_DECODER_STREAM_LOCK (dec);
      gst_audio_decoder_drain (dec);

      GST_DEBUG_OBJECT (dec, "received STREAM_START. Clearing taglist");
      /* Flush our merged taglist after a STREAM_START */
      if (dec->priv->taglist) {
        gst_tag_list_unref (dec->priv->taglist);
        dec->priv->taglist = NULL;
      }
      dec->priv->taglist_changed = FALSE;
      GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

      ret = gst_audio_decoder_push_event (dec, event);
      break;
    case GST_EVENT_SEGMENT:
    {
      GstSegment seg;
      GstFormat format;

      GST_AUDIO_DECODER_STREAM_LOCK (dec);
      gst_event_copy_segment (event, &seg);

      format = seg.format;
      if (format == GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_SEGMENT_FORMAT,
            &seg);
      } else {
        gint64 nstart;
        GST_DEBUG_OBJECT (dec, "received SEGMENT %" GST_SEGMENT_FORMAT, &seg);
        /* handle newsegment resulting from legacy simple seeking */
        /* note that we need to convert this whether or not enough data
         * to handle initial newsegment */
        if (dec->priv->ctx.do_estimate_rate &&
            gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, seg.start,
                GST_FORMAT_TIME, &nstart)) {
          /* best attempt convert */
          /* as these are only estimates, stop is kept open-ended to avoid
           * premature cutting */
          GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT,
              GST_TIME_ARGS (nstart));
          seg.format = GST_FORMAT_TIME;
          seg.start = nstart;
          seg.time = nstart;
          seg.stop = GST_CLOCK_TIME_NONE;
          /* replace event */
          gst_event_unref (event);
          event = gst_event_new_segment (&seg);
        } else {
          GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
          GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
          gst_event_unref (event);
          ret = FALSE;
          break;
        }
      }

      /* finish current segment */
      gst_audio_decoder_drain (dec);

      {
        /* prepare for next one */
        gst_audio_decoder_flush (dec, FALSE);
        /* and that's where we time from,
         * in case upstream does not come up with anything better
         * (e.g. upstream BYTE) */
        if (format != GST_FORMAT_TIME) {
          dec->priv->base_ts = seg.start;
          dec->priv->samples = 0;
        }
      }

      /* and follow along with segment */
      dec->input_segment = seg;
      dec->priv->pending_events =
          g_list_append (dec->priv->pending_events, event);
      GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

      ret = TRUE;
      break;
    }
    case GST_EVENT_GAP:
      ret = gst_audio_decoder_handle_gap (dec, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      GST_AUDIO_DECODER_STREAM_LOCK (dec);
      /* prepare for fresh start */
      gst_audio_decoder_flush (dec, TRUE);

      g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL);
      g_list_free (dec->priv->pending_events);
      dec->priv->pending_events = NULL;
      GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

      /* Forward FLUSH_STOP, it is expected to be forwarded immediately
       * and no buffers are queued anyway. */
      ret = gst_audio_decoder_push_event (dec, event);
      break;

    case GST_EVENT_EOS:
      GST_AUDIO_DECODER_STREAM_LOCK (dec);
      gst_audio_decoder_drain (dec);
      GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

      if (dec->priv->ctx.had_input_data && !dec->priv->ctx.had_output_data) {
        GST_ELEMENT_ERROR (dec, STREAM, DECODE,
            ("No valid frames decoded before end of stream"),
            ("no valid frames found"));
      }

      /* Forward EOS because no buffer or serialized event will come after
       * EOS and nothing could trigger another _finish_frame() call. */
      ret = gst_audio_decoder_push_event (dec, event);
      break;

    case GST_EVENT_CAPS:
    {
      ret = TRUE;
      dec->priv->do_caps = TRUE;
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_TAG:
    {
      GstTagList *tags;

      gst_event_parse_tag (event, &tags);

      if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM) {
        gst_audio_decoder_merge_tags (dec, tags, GST_TAG_MERGE_REPLACE);
        gst_event_unref (event);
        event = NULL;
        ret = TRUE;
        break;
      }

      /* fall through */
    }
    default:
      if (!GST_EVENT_IS_SERIALIZED (event)) {
        ret =
            gst_pad_event_default (dec->sinkpad, GST_OBJECT_CAST (dec), event);
      } else {
        GST_DEBUG_OBJECT (dec, "Enqueuing event %d, %s", GST_EVENT_TYPE (event),
            GST_EVENT_TYPE_NAME (event));
        GST_AUDIO_DECODER_STREAM_LOCK (dec);
        dec->priv->pending_events =
            g_list_append (dec->priv->pending_events, event);
        GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
        ret = TRUE;
      }
      break;
  }
  return ret;
}

static gboolean
gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstAudioDecoder *dec;
  GstAudioDecoderClass *klass;
  gboolean ret;

  dec = GST_AUDIO_DECODER (parent);
  klass = GST_AUDIO_DECODER_GET_CLASS (dec);

  GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
      GST_EVENT_TYPE_NAME (event));

  if (klass->sink_event)
    ret = klass->sink_event (dec, event);
  else {
    gst_event_unref (event);
    ret = FALSE;
  }
  return ret;
}

static gboolean
gst_audio_decoder_do_seek (GstAudioDecoder * dec, GstEvent * event)
{
  GstSeekFlags flags;
  GstSeekType start_type, end_type;
  GstFormat format;
  gdouble rate;
  gint64 start, start_time, end_time;
  GstSegment seek_segment;
  guint32 seqnum;

  gst_event_parse_seek (event, &rate, &format, &flags, &start_type,
      &start_time, &end_type, &end_time);

  /* we'll handle plain open-ended flushing seeks with the simple approach */
  if (rate != 1.0) {
    GST_DEBUG_OBJECT (dec, "unsupported seek: rate");
    return FALSE;
  }

  if (start_type != GST_SEEK_TYPE_SET) {
    GST_DEBUG_OBJECT (dec, "unsupported seek: start time");
    return FALSE;
  }

  if (end_type != GST_SEEK_TYPE_NONE ||
      (end_type == GST_SEEK_TYPE_SET && end_time != GST_CLOCK_TIME_NONE)) {
    GST_DEBUG_OBJECT (dec, "unsupported seek: end time");
    return FALSE;
  }

  if (!(flags & GST_SEEK_FLAG_FLUSH)) {
    GST_DEBUG_OBJECT (dec, "unsupported seek: not flushing");
    return FALSE;
  }

  memcpy (&seek_segment, &dec->output_segment, sizeof (seek_segment));
  gst_segment_do_seek (&seek_segment, rate, format, flags, start_type,
      start_time, end_type, end_time, NULL);
  start_time = seek_segment.position;

  if (!gst_pad_query_convert (dec->sinkpad, GST_FORMAT_TIME, start_time,
          GST_FORMAT_BYTES, &start)) {
    GST_DEBUG_OBJECT (dec, "conversion failed");
    return FALSE;
  }

  seqnum = gst_event_get_seqnum (event);
  event = gst_event_new_seek (1.0, GST_FORMAT_BYTES, flags,
      GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_NONE, -1);
  gst_event_set_seqnum (event, seqnum);

  GST_DEBUG_OBJECT (dec, "seeking to %" GST_TIME_FORMAT " at byte offset %"
      G_GINT64_FORMAT, GST_TIME_ARGS (start_time), start);

  return gst_pad_push_event (dec->sinkpad, event);
}

static gboolean
gst_audio_decoder_src_eventfunc (GstAudioDecoder * dec, GstEvent * event)
{
  gboolean res;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
    {
      GstFormat format;
      gdouble rate;
      GstSeekFlags flags;
      GstSeekType start_type, stop_type;
      gint64 start, stop;
      gint64 tstart, tstop;
      guint32 seqnum;

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

      /* upstream gets a chance first */
      if ((res = gst_pad_push_event (dec->sinkpad, event)))
        break;

      /* if upstream fails for a time seek, maybe we can help if allowed */
      if (format == GST_FORMAT_TIME) {
        if (gst_audio_decoder_do_byte (dec))
          res = gst_audio_decoder_do_seek (dec, event);
        break;
      }

      /* ... though a non-time seek can be aided as well */
      /* First bring the requested format to time */
      if (!(res =
              gst_pad_query_convert (dec->srcpad, format, start,
                  GST_FORMAT_TIME, &tstart)))
        goto convert_error;
      if (!(res =
              gst_pad_query_convert (dec->srcpad, format, stop, GST_FORMAT_TIME,
                  &tstop)))
        goto convert_error;

      /* then seek with time on the peer */
      event = gst_event_new_seek (rate, GST_FORMAT_TIME,
          flags, start_type, tstart, stop_type, tstop);
      gst_event_set_seqnum (event, seqnum);

      res = gst_pad_push_event (dec->sinkpad, event);
      break;
    }
    default:
      res = gst_pad_event_default (dec->srcpad, GST_OBJECT_CAST (dec), event);
      break;
  }
done:
  return res;

  /* ERRORS */
convert_error:
  {
    GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek");
    goto done;
  }
}

static gboolean
gst_audio_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstAudioDecoder *dec;
  GstAudioDecoderClass *klass;
  gboolean ret;

  dec = GST_AUDIO_DECODER (parent);
  klass = GST_AUDIO_DECODER_GET_CLASS (dec);

  GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
      GST_EVENT_TYPE_NAME (event));

  if (klass->src_event)
    ret = klass->src_event (dec, event);
  else {
    gst_event_unref (event);
    ret = FALSE;
  }

  return ret;
}

static gboolean
gst_audio_decoder_decide_allocation_default (GstAudioDecoder * dec,
    GstQuery * query)
{
  GstAllocator *allocator = NULL;
  GstAllocationParams params;
  gboolean update_allocator;

  /* we got configuration from our peer or the decide_allocation method,
   * parse them */
  if (gst_query_get_n_allocation_params (query) > 0) {
    /* try the allocator */
    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
    update_allocator = TRUE;
  } else {
    allocator = NULL;
    gst_allocation_params_init (&params);
    update_allocator = FALSE;
  }

  if (update_allocator)
    gst_query_set_nth_allocation_param (query, 0, allocator, &params);
  else
    gst_query_add_allocation_param (query, allocator, &params);
  if (allocator)
    gst_object_unref (allocator);

  return TRUE;
}

static gboolean
gst_audio_decoder_propose_allocation_default (GstAudioDecoder * dec,
    GstQuery * query)
{
  return TRUE;
}

/*
 * gst_audio_encoded_audio_convert:
 * @fmt: audio format of the encoded audio
 * @bytes: number of encoded bytes
 * @samples: number of encoded samples
 * @src_format: source format
 * @src_value: source value
 * @dest_format: destination format
 * @dest_value: destination format
 *
 * Helper function to convert @src_value in @src_format to @dest_value in
 * @dest_format for encoded audio data.  Conversion is possible between
 * BYTE and TIME format by using estimated bitrate based on
 * @samples and @bytes (and @fmt).
 */
/* FIXME: make gst_audio_encoded_audio_convert() public? */
static gboolean
gst_audio_encoded_audio_convert (GstAudioInfo * fmt,
    gint64 bytes, gint64 samples, GstFormat src_format,
    gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
{
  gboolean res = FALSE;

  g_return_val_if_fail (dest_format != NULL, FALSE);
  g_return_val_if_fail (dest_value != NULL, FALSE);

  if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
          src_value == -1)) {
    if (dest_value)
      *dest_value = src_value;
    return TRUE;
  }

  if (samples == 0 || bytes == 0 || fmt->rate == 0) {
    GST_DEBUG ("not enough metadata yet to convert");
    goto exit;
  }

  bytes *= fmt->rate;

  switch (src_format) {
    case GST_FORMAT_BYTES:
      switch (*dest_format) {
        case GST_FORMAT_TIME:
          *dest_value = gst_util_uint64_scale (src_value,
              GST_SECOND * samples, bytes);
          res = TRUE;
          break;
        default:
          res = FALSE;
      }
      break;
    case GST_FORMAT_TIME:
      switch (*dest_format) {
        case GST_FORMAT_BYTES:
          *dest_value = gst_util_uint64_scale (src_value, bytes,
              samples * GST_SECOND);
          res = TRUE;
          break;
        default:
          res = FALSE;
      }
      break;
    default:
      res = FALSE;
  }

exit:
  return res;
}

static gboolean
gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  gboolean res = FALSE;
  GstAudioDecoder *dec;

  dec = GST_AUDIO_DECODER (parent);

  GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_FORMATS:
    {
      gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);
      res = TRUE;
      break;
    }
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      if (!(res = gst_audio_encoded_audio_convert (&dec->priv->ctx.info,
                  dec->priv->bytes_in, dec->priv->samples_out,
                  src_fmt, src_val, &dest_fmt, &dest_val)))
        goto error;
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
    case GST_QUERY_ALLOCATION:
    {
      GstAudioDecoderClass *klass = GST_AUDIO_DECODER_GET_CLASS (dec);

      if (klass->propose_allocation)
        res = klass->propose_allocation (dec, query);
      break;
    }
    case GST_QUERY_SEEKING:
    {
      GstFormat format;

      /* non-TIME segments are discarded, so we won't seek that way either */
      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      if (format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (dec, "discarding non-TIME SEEKING query");
        res = FALSE;
        break;
      }
      /* fall-through */
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

error:
  return res;
}

/* FIXME ? are any of these queries (other than latency) a decoder's business ??
 * also, the conversion stuff might seem to make sense, but seems to not mind
 * segment stuff etc at all
 * Supposedly that's backward compatibility ... */
static gboolean
gst_audio_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstAudioDecoder *dec;
  gboolean res = FALSE;

  dec = GST_AUDIO_DECODER (parent);

  GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
    {
      GstFormat format;

      /* upstream in any case */
      if ((res = gst_pad_query_default (pad, parent, query)))
        break;

      gst_query_parse_duration (query, &format, NULL);
      /* try answering TIME by converting from BYTE if subclass allows  */
      if (format == GST_FORMAT_TIME && gst_audio_decoder_do_byte (dec)) {
        gint64 value;

        if (gst_pad_peer_query_duration (dec->sinkpad, GST_FORMAT_BYTES,
                &value)) {
          GST_LOG_OBJECT (dec, "upstream size %" G_GINT64_FORMAT, value);
          if (gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, value,
                  GST_FORMAT_TIME, &value)) {
            gst_query_set_duration (query, GST_FORMAT_TIME, value);
            res = TRUE;
          }
        }
      }
      break;
    }
    case GST_QUERY_POSITION:
    {
      GstFormat format;
      gint64 time, value;

      if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
        GST_LOG_OBJECT (dec, "returning peer response");
        break;
      }

      /* we start from the last seen time */
      time = dec->output_segment.position;
      /* correct for the segment values */
      time =
          gst_segment_to_stream_time (&dec->output_segment, GST_FORMAT_TIME,
          time);

      GST_LOG_OBJECT (dec,
          "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time));

      /* and convert to the final format */
      gst_query_parse_position (query, &format, NULL);
      if (!(res = gst_pad_query_convert (pad, GST_FORMAT_TIME, time,
                  format, &value)))
        break;

      gst_query_set_position (query, format, value);

      GST_LOG_OBJECT (dec,
          "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
          format);
      break;
    }
    case GST_QUERY_FORMATS:
    {
      gst_query_set_formats (query, 3,
          GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
      res = TRUE;
      break;
    }
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      if (!(res = gst_audio_info_convert (&dec->priv->ctx.info,
                  src_fmt, src_val, dest_fmt, &dest_val)))
        break;
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
    case GST_QUERY_LATENCY:
    {
      if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
        gboolean live;
        GstClockTime min_latency, max_latency;

        gst_query_parse_latency (query, &live, &min_latency, &max_latency);
        GST_DEBUG_OBJECT (dec, "Peer latency: live %d, min %"
            GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
            GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));

        GST_OBJECT_LOCK (dec);
        /* add our latency */
        if (min_latency != -1)
          min_latency += dec->priv->ctx.min_latency;
        if (max_latency != -1)
          max_latency += dec->priv->ctx.max_latency;
        GST_OBJECT_UNLOCK (dec);

        gst_query_set_latency (query, live, min_latency, max_latency);
      }
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

  return res;
}

static gboolean
gst_audio_decoder_stop (GstAudioDecoder * dec)
{
  GstAudioDecoderClass *klass;
  gboolean ret = TRUE;

  GST_DEBUG_OBJECT (dec, "gst_audio_decoder_stop");

  klass = GST_AUDIO_DECODER_GET_CLASS (dec);

  if (klass->stop) {
    ret = klass->stop (dec);
  }

  /* clean up */
  gst_audio_decoder_reset (dec, TRUE);

  if (ret)
    dec->priv->active = FALSE;

  return TRUE;
}

static gboolean
gst_audio_decoder_start (GstAudioDecoder * dec)
{
  GstAudioDecoderClass *klass;
  gboolean ret = TRUE;

  GST_DEBUG_OBJECT (dec, "gst_audio_decoder_start");

  klass = GST_AUDIO_DECODER_GET_CLASS (dec);

  /* arrange clean state */
  gst_audio_decoder_reset (dec, TRUE);

  if (klass->start) {
    ret = klass->start (dec);
  }

  if (ret)
    dec->priv->active = TRUE;

  return TRUE;
}

static void
gst_audio_decoder_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioDecoder *dec;

  dec = GST_AUDIO_DECODER (object);

  switch (prop_id) {
    case PROP_LATENCY:
      g_value_set_int64 (value, dec->priv->latency);
      break;
    case PROP_TOLERANCE:
      g_value_set_int64 (value, dec->priv->tolerance);
      break;
    case PROP_PLC:
      g_value_set_boolean (value, dec->priv->plc);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_audio_decoder_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioDecoder *dec;

  dec = GST_AUDIO_DECODER (object);

  switch (prop_id) {
    case PROP_LATENCY:
      dec->priv->latency = g_value_get_int64 (value);
      break;
    case PROP_TOLERANCE:
      dec->priv->tolerance = g_value_get_int64 (value);
      break;
    case PROP_PLC:
      dec->priv->plc = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_audio_decoder_change_state (GstElement * element, GstStateChange transition)
{
  GstAudioDecoder *codec;
  GstAudioDecoderClass *klass;
  GstStateChangeReturn ret;

  codec = GST_AUDIO_DECODER (element);
  klass = GST_AUDIO_DECODER_GET_CLASS (codec);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (klass->open) {
        if (!klass->open (codec))
          goto open_failed;
      }
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      if (!gst_audio_decoder_start (codec)) {
        goto start_failed;
      }
      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:
      if (!gst_audio_decoder_stop (codec)) {
        goto stop_failed;
      }
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      if (klass->close) {
        if (!klass->close (codec))
          goto close_failed;
      }
      break;
    default:
      break;
  }

  return ret;

start_failed:
  {
    GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to start codec"));
    return GST_STATE_CHANGE_FAILURE;
  }
stop_failed:
  {
    GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to stop codec"));
    return GST_STATE_CHANGE_FAILURE;
  }
open_failed:
  {
    GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to open codec"));
    return GST_STATE_CHANGE_FAILURE;
  }
close_failed:
  {
    GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to close codec"));
    return GST_STATE_CHANGE_FAILURE;
  }
}

GstFlowReturn
_gst_audio_decoder_error (GstAudioDecoder * dec, gint weight,
    GQuark domain, gint code, gchar * txt, gchar * dbg, const gchar * file,
    const gchar * function, gint line)
{
  if (txt)
    GST_WARNING_OBJECT (dec, "error: %s", txt);
  if (dbg)
    GST_WARNING_OBJECT (dec, "error: %s", dbg);
  dec->priv->error_count += weight;
  dec->priv->discont = TRUE;
  if (dec->priv->ctx.max_errors >= 0
      && dec->priv->ctx.max_errors < dec->priv->error_count) {
    gst_element_message_full (GST_ELEMENT (dec), GST_MESSAGE_ERROR, domain,
        code, txt, dbg, file, function, line);
    return GST_FLOW_ERROR;
  } else {
    g_free (txt);
    g_free (dbg);
    return GST_FLOW_OK;
  }
}

/**
 * gst_audio_decoder_get_audio_info:
 * @dec: a #GstAudioDecoder
 *
 * Returns: a #GstAudioInfo describing the input audio format
 */
GstAudioInfo *
gst_audio_decoder_get_audio_info (GstAudioDecoder * dec)
{
  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), NULL);

  return &dec->priv->ctx.info;
}

/**
 * gst_audio_decoder_set_plc_aware:
 * @dec: a #GstAudioDecoder
 * @plc: new plc state
 *
 * Indicates whether or not subclass handles packet loss concealment (plc).
 */
void
gst_audio_decoder_set_plc_aware (GstAudioDecoder * dec, gboolean plc)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  dec->priv->ctx.do_plc = plc;
}

/**
 * gst_audio_decoder_get_plc_aware:
 * @dec: a #GstAudioDecoder
 *
 * Returns: currently configured plc handling
 */
gint
gst_audio_decoder_get_plc_aware (GstAudioDecoder * dec)
{
  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);

  return dec->priv->ctx.do_plc;
}

/**
 * gst_audio_decoder_set_estimate_rate:
 * @dec: a #GstAudioDecoder
 * @enabled: whether to enable byte to time conversion
 *
 * Allows baseclass to perform byte to time estimated conversion.
 */
void
gst_audio_decoder_set_estimate_rate (GstAudioDecoder * dec, gboolean enabled)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  dec->priv->ctx.do_estimate_rate = enabled;
}

/**
 * gst_audio_decoder_get_estimate_rate:
 * @dec: a #GstAudioDecoder
 *
 * Returns: currently configured byte to time conversion setting
 */
gint
gst_audio_decoder_get_estimate_rate (GstAudioDecoder * dec)
{
  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);

  return dec->priv->ctx.do_estimate_rate;
}

/**
 * gst_audio_decoder_get_delay:
 * @dec: a #GstAudioDecoder
 *
 * Returns: currently configured decoder delay
 */
gint
gst_audio_decoder_get_delay (GstAudioDecoder * dec)
{
  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);

  return dec->priv->ctx.delay;
}

/**
 * gst_audio_decoder_set_max_errors:
 * @dec: a #GstAudioDecoder
 * @num: max tolerated errors
 *
 * Sets numbers of tolerated decoder errors, where a tolerated one is then only
 * warned about, but more than tolerated will lead to fatal error. You can set
 * -1 for never returning fatal errors. Default is set to
 * GST_AUDIO_DECODER_MAX_ERRORS.
 */
void
gst_audio_decoder_set_max_errors (GstAudioDecoder * dec, gint num)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  dec->priv->ctx.max_errors = num;
}

/**
 * gst_audio_decoder_get_max_errors:
 * @dec: a #GstAudioDecoder
 *
 * Returns: currently configured decoder tolerated error count.
 */
gint
gst_audio_decoder_get_max_errors (GstAudioDecoder * dec)
{
  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);

  return dec->priv->ctx.max_errors;
}

/**
 * gst_audio_decoder_set_latency:
 * @dec: a #GstAudioDecoder
 * @min: minimum latency
 * @max: maximum latency
 *
 * Sets decoder latency.
 */
void
gst_audio_decoder_set_latency (GstAudioDecoder * dec,
    GstClockTime min, GstClockTime max)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  GST_OBJECT_LOCK (dec);
  dec->priv->ctx.min_latency = min;
  dec->priv->ctx.max_latency = max;
  GST_OBJECT_UNLOCK (dec);
}

/**
 * gst_audio_decoder_get_latency:
 * @dec: a #GstAudioDecoder
 * @min: (out) (allow-none): a pointer to storage to hold minimum latency
 * @max: (out) (allow-none): a pointer to storage to hold maximum latency
 *
 * Sets the variables pointed to by @min and @max to the currently configured
 * latency.
 */
void
gst_audio_decoder_get_latency (GstAudioDecoder * dec,
    GstClockTime * min, GstClockTime * max)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  GST_OBJECT_LOCK (dec);
  if (min)
    *min = dec->priv->ctx.min_latency;
  if (max)
    *max = dec->priv->ctx.max_latency;
  GST_OBJECT_UNLOCK (dec);
}

/**
 * gst_audio_decoder_get_parse_state:
 * @dec: a #GstAudioDecoder
 * @sync: a pointer to a variable to hold the current sync state
 * @eos: a pointer to a variable to hold the current eos state
 *
 * Return current parsing (sync and eos) state.
 */
void
gst_audio_decoder_get_parse_state (GstAudioDecoder * dec,
    gboolean * sync, gboolean * eos)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  if (sync)
    *sync = dec->priv->ctx.sync;
  if (eos)
    *eos = dec->priv->ctx.eos;
}

/**
 * gst_audio_decoder_set_plc:
 * @dec: a #GstAudioDecoder
 * @enabled: new state
 *
 * Enable or disable decoder packet loss concealment, provided subclass
 * and codec are capable and allow handling plc.
 *
 * MT safe.
 */
void
gst_audio_decoder_set_plc (GstAudioDecoder * dec, gboolean enabled)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  GST_LOG_OBJECT (dec, "enabled: %d", enabled);

  GST_OBJECT_LOCK (dec);
  dec->priv->plc = enabled;
  GST_OBJECT_UNLOCK (dec);
}

/**
 * gst_audio_decoder_get_plc:
 * @dec: a #GstAudioDecoder
 *
 * Queries decoder packet loss concealment handling.
 *
 * Returns: TRUE if packet loss concealment is enabled.
 *
 * MT safe.
 */
gboolean
gst_audio_decoder_get_plc (GstAudioDecoder * dec)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);

  GST_OBJECT_LOCK (dec);
  result = dec->priv->plc;
  GST_OBJECT_UNLOCK (dec);

  return result;
}

/**
 * gst_audio_decoder_set_min_latency:
 * @dec: a #GstAudioDecoder
 * @num: new minimum latency
 *
 * Sets decoder minimum aggregation latency.
 *
 * MT safe.
 */
void
gst_audio_decoder_set_min_latency (GstAudioDecoder * dec, GstClockTime num)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  GST_OBJECT_LOCK (dec);
  dec->priv->latency = num;
  GST_OBJECT_UNLOCK (dec);
}

/**
 * gst_audio_decoder_get_min_latency:
 * @dec: a #GstAudioDecoder
 *
 * Queries decoder's latency aggregation.
 *
 * Returns: aggregation latency.
 *
 * MT safe.
 */
GstClockTime
gst_audio_decoder_get_min_latency (GstAudioDecoder * dec)
{
  GstClockTime result;

  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);

  GST_OBJECT_LOCK (dec);
  result = dec->priv->latency;
  GST_OBJECT_UNLOCK (dec);

  return result;
}

/**
 * gst_audio_decoder_set_tolerance:
 * @dec: a #GstAudioDecoder
 * @tolerance: new tolerance
 *
 * Configures decoder audio jitter tolerance threshold.
 *
 * MT safe.
 */
void
gst_audio_decoder_set_tolerance (GstAudioDecoder * dec, GstClockTime tolerance)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  GST_OBJECT_LOCK (dec);
  dec->priv->tolerance = tolerance;
  GST_OBJECT_UNLOCK (dec);
}

/**
 * gst_audio_decoder_get_tolerance:
 * @dec: a #GstAudioDecoder
 *
 * Queries current audio jitter tolerance threshold.
 *
 * Returns: decoder audio jitter tolerance threshold.
 *
 * MT safe.
 */
GstClockTime
gst_audio_decoder_get_tolerance (GstAudioDecoder * dec)
{
  GstClockTime result;

  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);

  GST_OBJECT_LOCK (dec);
  result = dec->priv->tolerance;
  GST_OBJECT_UNLOCK (dec);

  return result;
}

/**
 * gst_audio_decoder_set_drainable:
 * @dec: a #GstAudioDecoder
 * @enabled: new state
 *
 * Configures decoder drain handling.  If drainable, subclass might
 * be handed a NULL buffer to have it return any leftover decoded data.
 * Otherwise, it is not considered so capable and will only ever be passed
 * real data.
 *
 * MT safe.
 */
void
gst_audio_decoder_set_drainable (GstAudioDecoder * dec, gboolean enabled)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  GST_OBJECT_LOCK (dec);
  dec->priv->drainable = enabled;
  GST_OBJECT_UNLOCK (dec);
}

/**
 * gst_audio_decoder_get_drainable:
 * @dec: a #GstAudioDecoder
 *
 * Queries decoder drain handling.
 *
 * Returns: TRUE if drainable handling is enabled.
 *
 * MT safe.
 */
gboolean
gst_audio_decoder_get_drainable (GstAudioDecoder * dec)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);

  GST_OBJECT_LOCK (dec);
  result = dec->priv->drainable;
  GST_OBJECT_UNLOCK (dec);

  return result;
}

/**
 * gst_audio_decoder_set_needs_format:
 * @dec: a #GstAudioDecoder
 * @enabled: new state
 *
 * Configures decoder format needs.  If enabled, subclass needs to be
 * negotiated with format caps before it can process any data.  It will then
 * never be handed any data before it has been configured.
 * Otherwise, it might be handed data without having been configured and
 * is then expected being able to do so either by default
 * or based on the input data.
 *
 * MT safe.
 */
void
gst_audio_decoder_set_needs_format (GstAudioDecoder * dec, gboolean enabled)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  GST_OBJECT_LOCK (dec);
  dec->priv->needs_format = enabled;
  GST_OBJECT_UNLOCK (dec);
}

/**
 * gst_audio_decoder_get_needs_format:
 * @dec: a #GstAudioDecoder
 *
 * Queries decoder required format handling.
 *
 * Returns: TRUE if required format handling is enabled.
 *
 * MT safe.
 */
gboolean
gst_audio_decoder_get_needs_format (GstAudioDecoder * dec)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);

  GST_OBJECT_LOCK (dec);
  result = dec->priv->needs_format;
  GST_OBJECT_UNLOCK (dec);

  return result;
}

/**
 * gst_audio_decoder_merge_tags:
 * @dec: a #GstAudioDecoder
 * @tags: a #GstTagList to merge
 * @mode: the #GstTagMergeMode to use
 *
 * Adds tags to so-called pending tags, which will be processed
 * before pushing out data downstream.
 *
 * Note that this is provided for convenience, and the subclass is
 * not required to use this and can still do tag handling on its own,
 * although it should be aware that baseclass already takes care
 * of the usual CODEC/AUDIO_CODEC tags.
 *
 * MT safe.
 */
void
gst_audio_decoder_merge_tags (GstAudioDecoder * dec,
    const GstTagList * tags, GstTagMergeMode mode)
{
  GstTagList *otags;

  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
  g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));

  GST_AUDIO_DECODER_STREAM_LOCK (dec);
  if (tags)
    GST_DEBUG_OBJECT (dec, "merging tags %" GST_PTR_FORMAT, tags);
  otags = dec->priv->taglist;
  dec->priv->taglist = gst_tag_list_merge (dec->priv->taglist, tags, mode);
  if (otags)
    gst_tag_list_unref (otags);
  dec->priv->taglist_changed = TRUE;
  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
}

/**
 * gst_audio_decoder_allocate_output_buffer:
 * @dec: a #GstAudioDecoder
 * @size: size of the buffer
 *
 * Helper function that allocates a buffer to hold an audio frame
 * for @dec's current output format.
 *
 * Returns: (transfer full): allocated buffer
 */
GstBuffer *
gst_audio_decoder_allocate_output_buffer (GstAudioDecoder * dec, gsize size)
{
  GstBuffer *buffer = NULL;
  gboolean needs_reconfigure = FALSE;

  g_return_val_if_fail (size > 0, NULL);

  GST_DEBUG ("alloc src buffer");

  GST_AUDIO_DECODER_STREAM_LOCK (dec);

  needs_reconfigure = gst_pad_check_reconfigure (dec->srcpad);
  if (G_UNLIKELY (dec->priv->ctx.output_format_changed ||
          (GST_AUDIO_INFO_IS_VALID (&dec->priv->ctx.info)
              && needs_reconfigure))) {
    if (!gst_audio_decoder_negotiate_unlocked (dec)) {
      GST_INFO_OBJECT (dec, "Failed to negotiate, fallback allocation");
      gst_pad_mark_reconfigure (dec->srcpad);
      goto fallback;
    }
  }

  buffer =
      gst_buffer_new_allocate (dec->priv->ctx.allocator, size,
      &dec->priv->ctx.params);
  if (!buffer) {
    GST_INFO_OBJECT (dec, "couldn't allocate output buffer");
    goto fallback;
  }

  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

  return buffer;
fallback:
  buffer = gst_buffer_new_allocate (NULL, size, NULL);
  GST_AUDIO_DECODER_STREAM_UNLOCK (dec);

  return buffer;
}

/**
 * gst_audio_decoder_get_allocator:
 * @dec: a #GstAudioDecoder
 * @allocator: (out) (allow-none) (transfer full): the #GstAllocator
 * used
 * @params: (out) (allow-none) (transfer full): the
 * #GstAllocatorParams of @allocator
 *
 * Lets #GstAudioDecoder sub-classes to know the memory @allocator
 * used by the base class and its @params.
 *
 * Unref the @allocator after use it.
 */
void
gst_audio_decoder_get_allocator (GstAudioDecoder * dec,
    GstAllocator ** allocator, GstAllocationParams * params)
{
  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));

  if (allocator)
    *allocator = dec->priv->ctx.allocator ?
        gst_object_ref (dec->priv->ctx.allocator) : NULL;

  if (params)
    *params = dec->priv->ctx.params;
}
