/* GStreamer
 * 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:gstaudioencoder
 * @short_description: Base class for audio encoders
 * @see_also: #GstBaseTransform
 *
 * This base class is for audio encoders turning raw audio samples into
 * encoded audio data.
 *
 * GstAudioEncoder and subclass should cooperate as follows.
 * <orderedlist>
 * <listitem>
 *   <itemizedlist><title>Configuration</title>
 *   <listitem><para>
 *     Initially, GstAudioEncoder calls @start when the encoder element
 *     is activated, which allows subclass to perform any global setup.
 *   </para></listitem>
 *   <listitem><para>
 *     GstAudioEncoder calls @set_format to inform subclass of the format
 *     of input audio data that it is about to receive.  Subclass should
 *     setup for encoding and configure various base class parameters
 *     appropriately, notably those directing desired input data handling.
 *     While unlikely, it might be called more than once, if changing input
 *     parameters require reconfiguration.
 *   </para></listitem>
 *   <listitem><para>
 *     GstAudioEncoder calls @stop at end of all processing.
 *   </para></listitem>
 *   </itemizedlist>
 * </listitem>
 * As of configuration stage, and throughout processing, GstAudioEncoder
 * maintains various parameters that provide required context,
 * e.g. describing the format of input audio data.
 * Conversely, subclass can and should configure these context parameters
 * to inform base class of its expectation w.r.t. buffer handling.
 * <listitem>
 *   <itemizedlist>
 *   <title>Data processing</title>
 *     <listitem><para>
 *       Base class gathers input sample data (as directed by the context's
 *       frame_samples and frame_max) and provides this to subclass' @handle_frame.
 *     </para></listitem>
 *     <listitem><para>
 *       If codec processing results in encoded data, subclass should call
 *       gst_audio_encoder_finish_frame() to have encoded data pushed
 *       downstream. Alternatively, it might also call
 *       gst_audio_encoder_finish_frame() (with a NULL buffer and some number of
 *       dropped samples) to indicate dropped (non-encoded) samples.
 *     </para></listitem>
 *     <listitem><para>
 *       Just prior to actually pushing a buffer downstream,
 *       it is passed to @pre_push.
 *     </para></listitem>
 *     <listitem><para>
 *       During the parsing process GstAudioEncoderClass 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>
 *     GstAudioEncoder 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_encoder_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 either favor tracking upstream timestamps
 * (at the possible expense of jitter) or aim to arrange for a perfect stream of
 * output timestamps, depending on #GstAudioEncoder:perfect-timestamp.
 * However, in the latter case, the input may not be so perfect or ideal, which
 * is handled as follows.  An input timestamp is compared with the expected
 * timestamp as dictated by input sample stream and if the deviation is less
 * than #GstAudioEncoder:tolerance, the deviation is discarded.
 * Otherwise, it is considered a discontuinity and subsequent output timestamp
 * is resynced to the new position after performing configured discontinuity
 * processing.  In the non-perfect-timestamp case, an upstream variation
 * exceeding tolerance only leads to marking DISCONT on subsequent outgoing
 * (while timestamps are adjusted to upstream regardless of variation).
 * While DISCONT is also marked in the perfect-timestamp case, this one
 * optionally (see #GstAudioEncoder:hard-resync)
 * performs some additional steps, such as clipping of (early) input samples
 * or draining all currently remaining input data, depending on the direction
 * of the discontuinity.
 *
 * If perfect timestamps are arranged, it is also possible to request baseclass
 * (usually set by subclass) to provide additional buffer metadata (in OFFSET
 * and OFFSET_END) fields according to granule defined semantics currently
 * needed by oggmux.  Specifically, OFFSET is set to granulepos (= sample count
 * including buffer) and OFFSET_END to corresponding timestamp (as determined
 * by same sample count and sample rate).
 *
 * 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>
 *      Inform base class of buffer processing needs using context's
 *      frame_samples and frame_bytes.
 *   </para></listitem>
 *   <listitem><para>
 *      Set user-configurable properties to sane defaults for format and
 *      implementing codec at hand, e.g. those controlling timestamp behaviour
 *      and discontinuity processing.
 *   </para></listitem>
 *   <listitem><para>
 *      Accept data in @handle_frame and provide encoded results to
 *      gst_audio_encoder_finish_frame().
 *   </para></listitem>
 * </itemizedlist>
 *
 */

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

#include "gstaudioencoder.h"
#include "gstaudioutilsprivate.h"
#include <gst/base/gstadapter.h>
#include <gst/audio/audio.h>
#include <gst/pbutils/descriptions.h>

#include <stdlib.h>
#include <string.h>


GST_DEBUG_CATEGORY_STATIC (gst_audio_encoder_debug);
#define GST_CAT_DEFAULT gst_audio_encoder_debug

#define GST_AUDIO_ENCODER_GET_PRIVATE(obj)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_ENCODER, \
        GstAudioEncoderPrivate))

enum
{
  PROP_0,
  PROP_PERFECT_TS,
  PROP_GRANULE,
  PROP_HARD_RESYNC,
  PROP_TOLERANCE
};

#define DEFAULT_PERFECT_TS   FALSE
#define DEFAULT_GRANULE      FALSE
#define DEFAULT_HARD_RESYNC  FALSE
#define DEFAULT_TOLERANCE    40000000
#define DEFAULT_HARD_MIN     FALSE
#define DEFAULT_DRAINABLE    TRUE

typedef struct _GstAudioEncoderContext
{
  /* input */
  /* last negotiated input caps */
  GstCaps *input_caps;
  /* last negotiated input info */
  GstAudioInfo info;

  /* output */
  GstCaps *caps;
  GstCaps *allocation_caps;
  gboolean output_caps_changed;
  gint frame_samples_min, frame_samples_max;
  gint frame_max;
  gint lookahead;
  /* MT-protected (with LOCK) */
  GstClockTime min_latency;
  GstClockTime max_latency;

  GList *headers;
  gboolean new_headers;

  GstAllocator *allocator;
  GstAllocationParams params;
} GstAudioEncoderContext;

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

  /* input base/first ts as basis for output ts;
   * kept nearly constant for perfect_ts,
   * otherwise resyncs to upstream ts */
  GstClockTime base_ts;
  /* corresponding base granulepos */
  gint64 base_gp;
  /* input samples processed and sent downstream so far (w.r.t. base_ts) */
  guint64 samples;

  /* currently collected sample data */
  GstAdapter *adapter;
  /* offset in adapter up to which already supplied to encoder */
  gint offset;
  /* mark outgoing discont */
  gboolean discont;
  /* to guess duration of drained data */
  GstClockTime last_duration;

  /* subclass provided data in processing round */
  gboolean got_data;
  /* subclass gave all it could already */
  gboolean drained;
  /* subclass currently being forcibly drained */
  gboolean force;
  /* need to handle changed input caps */
  gboolean do_caps;

  /* output bps estimatation */
  /* global in samples seen */
  guint64 samples_in;
  /* global bytes sent out */
  guint64 bytes_out;

  /* context storage */
  GstAudioEncoderContext ctx;

  /* properties */
  gint64 tolerance;
  gboolean perfect_ts;
  gboolean hard_resync;
  gboolean granule;
  gboolean hard_min;
  gboolean drainable;

  /* upstream stream tags (global tags are passed through as-is) */
  GstTagList *upstream_tags;

  /* subclass tags */
  GstTagList *tags;
  GstTagMergeMode tags_merge_mode;

  gboolean tags_changed;

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


static GstElementClass *parent_class = NULL;

static void gst_audio_encoder_class_init (GstAudioEncoderClass * klass);
static void gst_audio_encoder_init (GstAudioEncoder * parse,
    GstAudioEncoderClass * klass);

GType
gst_audio_encoder_get_type (void)
{
  static GType audio_encoder_type = 0;

  if (!audio_encoder_type) {
    static const GTypeInfo audio_encoder_info = {
      sizeof (GstAudioEncoderClass),
      (GBaseInitFunc) NULL,
      (GBaseFinalizeFunc) NULL,
      (GClassInitFunc) gst_audio_encoder_class_init,
      NULL,
      NULL,
      sizeof (GstAudioEncoder),
      0,
      (GInstanceInitFunc) gst_audio_encoder_init,
    };
    const GInterfaceInfo preset_interface_info = {
      NULL,                     /* interface_init */
      NULL,                     /* interface_finalize */
      NULL                      /* interface_data */
    };

    audio_encoder_type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstAudioEncoder", &audio_encoder_info, G_TYPE_FLAG_ABSTRACT);

    g_type_add_interface_static (audio_encoder_type, GST_TYPE_PRESET,
        &preset_interface_info);
  }
  return audio_encoder_type;
}

static void gst_audio_encoder_finalize (GObject * object);
static void gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full);

static void gst_audio_encoder_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_audio_encoder_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

static gboolean gst_audio_encoder_sink_activate_mode (GstPad * pad,
    GstObject * parent, GstPadMode mode, gboolean active);

static GstCaps *gst_audio_encoder_getcaps_default (GstAudioEncoder * enc,
    GstCaps * filter);

static gboolean gst_audio_encoder_sink_event_default (GstAudioEncoder * enc,
    GstEvent * event);
static gboolean gst_audio_encoder_src_event_default (GstAudioEncoder * enc,
    GstEvent * event);
static gboolean gst_audio_encoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_audio_encoder_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_audio_encoder_sink_setcaps (GstAudioEncoder * enc,
    GstCaps * caps);
static GstFlowReturn gst_audio_encoder_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static gboolean gst_audio_encoder_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_audio_encoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstStateChangeReturn gst_audio_encoder_change_state (GstElement *
    element, GstStateChange transition);

static gboolean gst_audio_encoder_decide_allocation_default (GstAudioEncoder *
    enc, GstQuery * query);
static gboolean gst_audio_encoder_propose_allocation_default (GstAudioEncoder *
    enc, GstQuery * query);
static gboolean gst_audio_encoder_negotiate_default (GstAudioEncoder * enc);
static gboolean gst_audio_encoder_negotiate_unlocked (GstAudioEncoder * enc);

static gboolean gst_audio_encoder_transform_meta_default (GstAudioEncoder *
    encoder, GstBuffer * outbuf, GstMeta * meta, GstBuffer * inbuf);

static gboolean gst_audio_encoder_sink_query_default (GstAudioEncoder * encoder,
    GstQuery * query);
static gboolean gst_audio_encoder_src_query_default (GstAudioEncoder * encoder,
    GstQuery * query);

static void
gst_audio_encoder_class_init (GstAudioEncoderClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  parent_class = g_type_class_peek_parent (klass);

  GST_DEBUG_CATEGORY_INIT (gst_audio_encoder_debug, "audioencoder", 0,
      "audio encoder base class");

  g_type_class_add_private (klass, sizeof (GstAudioEncoderPrivate));

  gobject_class->set_property = gst_audio_encoder_set_property;
  gobject_class->get_property = gst_audio_encoder_get_property;

  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_audio_encoder_finalize);

  /* properties */
  g_object_class_install_property (gobject_class, PROP_PERFECT_TS,
      g_param_spec_boolean ("perfect-timestamp", "Perfect Timestamps",
          "Favour perfect timestamps over tracking upstream timestamps",
          DEFAULT_PERFECT_TS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_GRANULE,
      g_param_spec_boolean ("mark-granule", "Granule Marking",
          "Apply granule semantics to buffer metadata (implies perfect-timestamp)",
          DEFAULT_GRANULE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_HARD_RESYNC,
      g_param_spec_boolean ("hard-resync", "Hard Resync",
          "Perform clipping and sample flushing upon discontinuity",
          DEFAULT_HARD_RESYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_TOLERANCE,
      g_param_spec_int64 ("tolerance", "Tolerance",
          "Consider discontinuity if timestamp jitter/imperfection exceeds tolerance (ns)",
          0, G_MAXINT64, DEFAULT_TOLERANCE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_audio_encoder_change_state);

  klass->getcaps = gst_audio_encoder_getcaps_default;
  klass->sink_event = gst_audio_encoder_sink_event_default;
  klass->src_event = gst_audio_encoder_src_event_default;
  klass->sink_query = gst_audio_encoder_sink_query_default;
  klass->src_query = gst_audio_encoder_src_query_default;
  klass->propose_allocation = gst_audio_encoder_propose_allocation_default;
  klass->decide_allocation = gst_audio_encoder_decide_allocation_default;
  klass->negotiate = gst_audio_encoder_negotiate_default;
  klass->transform_meta = gst_audio_encoder_transform_meta_default;
}

static void
gst_audio_encoder_init (GstAudioEncoder * enc, GstAudioEncoderClass * bclass)
{
  GstPadTemplate *pad_template;

  GST_DEBUG_OBJECT (enc, "gst_audio_encoder_init");

  enc->priv = GST_AUDIO_ENCODER_GET_PRIVATE (enc);

  /* only push mode supported */
  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "sink");
  g_return_if_fail (pad_template != NULL);
  enc->sinkpad = gst_pad_new_from_template (pad_template, "sink");
  gst_pad_set_event_function (enc->sinkpad,
      GST_DEBUG_FUNCPTR (gst_audio_encoder_sink_event));
  gst_pad_set_query_function (enc->sinkpad,
      GST_DEBUG_FUNCPTR (gst_audio_encoder_sink_query));
  gst_pad_set_chain_function (enc->sinkpad,
      GST_DEBUG_FUNCPTR (gst_audio_encoder_chain));
  gst_pad_set_activatemode_function (enc->sinkpad,
      GST_DEBUG_FUNCPTR (gst_audio_encoder_sink_activate_mode));
  gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);

  GST_DEBUG_OBJECT (enc, "sinkpad created");

  /* and we don't mind upstream traveling stuff that much ... */
  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
  g_return_if_fail (pad_template != NULL);
  enc->srcpad = gst_pad_new_from_template (pad_template, "src");
  gst_pad_set_event_function (enc->srcpad,
      GST_DEBUG_FUNCPTR (gst_audio_encoder_src_event));
  gst_pad_set_query_function (enc->srcpad,
      GST_DEBUG_FUNCPTR (gst_audio_encoder_src_query));
  gst_pad_use_fixed_caps (enc->srcpad);
  gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
  GST_DEBUG_OBJECT (enc, "src created");

  enc->priv->adapter = gst_adapter_new ();

  g_rec_mutex_init (&enc->stream_lock);

  /* property default */
  enc->priv->granule = DEFAULT_GRANULE;
  enc->priv->perfect_ts = DEFAULT_PERFECT_TS;
  enc->priv->hard_resync = DEFAULT_HARD_RESYNC;
  enc->priv->tolerance = DEFAULT_TOLERANCE;
  enc->priv->hard_min = DEFAULT_HARD_MIN;
  enc->priv->drainable = DEFAULT_DRAINABLE;

  /* init state */
  enc->priv->ctx.min_latency = 0;
  enc->priv->ctx.max_latency = 0;
  gst_audio_encoder_reset (enc, TRUE);
  GST_DEBUG_OBJECT (enc, "init ok");
}

static void
gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full)
{
  GST_AUDIO_ENCODER_STREAM_LOCK (enc);

  GST_LOG_OBJECT (enc, "reset full %d", full);

  if (full) {
    enc->priv->active = FALSE;
    GST_OBJECT_LOCK (enc);
    enc->priv->samples_in = 0;
    enc->priv->bytes_out = 0;
    GST_OBJECT_UNLOCK (enc);

    g_list_foreach (enc->priv->ctx.headers, (GFunc) gst_buffer_unref, NULL);
    g_list_free (enc->priv->ctx.headers);
    enc->priv->ctx.headers = NULL;
    enc->priv->ctx.new_headers = FALSE;

    if (enc->priv->ctx.allocator)
      gst_object_unref (enc->priv->ctx.allocator);
    enc->priv->ctx.allocator = NULL;

    GST_OBJECT_LOCK (enc);
    gst_caps_replace (&enc->priv->ctx.input_caps, NULL);
    gst_caps_replace (&enc->priv->ctx.caps, NULL);
    gst_caps_replace (&enc->priv->ctx.allocation_caps, NULL);

    memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
    gst_audio_info_init (&enc->priv->ctx.info);
    GST_OBJECT_UNLOCK (enc);

    if (enc->priv->upstream_tags) {
      gst_tag_list_unref (enc->priv->upstream_tags);
      enc->priv->upstream_tags = NULL;
    }
    if (enc->priv->tags)
      gst_tag_list_unref (enc->priv->tags);
    enc->priv->tags = NULL;
    enc->priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
    enc->priv->tags_changed = FALSE;

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

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

  gst_adapter_clear (enc->priv->adapter);
  enc->priv->got_data = FALSE;
  enc->priv->drained = TRUE;
  enc->priv->offset = 0;
  enc->priv->base_ts = GST_CLOCK_TIME_NONE;
  enc->priv->base_gp = -1;
  enc->priv->samples = 0;
  enc->priv->discont = FALSE;

  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
}

static void
gst_audio_encoder_finalize (GObject * object)
{
  GstAudioEncoder *enc = GST_AUDIO_ENCODER (object);

  g_object_unref (enc->priv->adapter);

  g_rec_mutex_clear (&enc->stream_lock);

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

static GstStateChangeReturn
gst_audio_encoder_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstAudioEncoder *enc = GST_AUDIO_ENCODER (element);
  GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (klass->open) {
        if (!klass->open (enc))
          goto open_failed;
      }
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
      if (klass->close) {
        if (!klass->close (enc))
          goto close_failed;
      }
    default:
      break;
  }

  return ret;

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

static gboolean
gst_audio_encoder_push_event (GstAudioEncoder * enc, GstEvent * event)
{
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:{
      GstSegment seg;

      GST_AUDIO_ENCODER_STREAM_LOCK (enc);
      gst_event_copy_segment (event, &seg);

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

      enc->output_segment = seg;
      GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
      break;
    }
    default:
      break;
  }

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

static inline void
gst_audio_encoder_push_pending_events (GstAudioEncoder * enc)
{
  GstAudioEncoderPrivate *priv = enc->priv;

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

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

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

static GstEvent *
gst_audio_encoder_create_merged_tags_event (GstAudioEncoder * enc)
{
  GstTagList *merged_tags;

  GST_LOG_OBJECT (enc, "upstream : %" GST_PTR_FORMAT, enc->priv->upstream_tags);
  GST_LOG_OBJECT (enc, "encoder  : %" GST_PTR_FORMAT, enc->priv->tags);
  GST_LOG_OBJECT (enc, "mode     : %d", enc->priv->tags_merge_mode);

  merged_tags =
      gst_tag_list_merge (enc->priv->upstream_tags, enc->priv->tags,
      enc->priv->tags_merge_mode);

  GST_DEBUG_OBJECT (enc, "merged   : %" GST_PTR_FORMAT, merged_tags);

  if (merged_tags == NULL)
    return NULL;

  if (gst_tag_list_is_empty (merged_tags)) {
    gst_tag_list_unref (merged_tags);
    return NULL;
  }

  /* add codec info to pending tags */
#if 0
  caps = gst_pad_get_current_caps (enc->srcpad);
  gst_pb_utils_add_codec_description_to_tag_list (merged_tags,
      GST_TAG_AUDIO_CODEC, caps);
#endif

  return gst_event_new_tag (merged_tags);
}

static void
gst_audio_encoder_check_and_push_pending_tags (GstAudioEncoder * enc)
{
  if (enc->priv->tags_changed) {
    GstEvent *tags_event;

    tags_event = gst_audio_encoder_create_merged_tags_event (enc);

    if (tags_event != NULL)
      gst_audio_encoder_push_event (enc, tags_event);

    enc->priv->tags_changed = FALSE;
  }
}


static gboolean
gst_audio_encoder_transform_meta_default (GstAudioEncoder *
    encoder, GstBuffer * outbuf, GstMeta * meta, GstBuffer * inbuf)
{
  const GstMetaInfo *info = meta->info;
  const gchar *const *tags;

  tags = gst_meta_api_type_get_tags (info->api);

  if (!tags || (g_strv_length ((gchar **) tags) == 1
          && gst_meta_api_type_has_tag (info->api,
              g_quark_from_string (GST_META_TAG_AUDIO_STR))))
    return TRUE;

  return FALSE;
}

typedef struct
{
  GstAudioEncoder *encoder;
  GstBuffer *outbuf;
} CopyMetaData;

static gboolean
foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
{
  CopyMetaData *data = user_data;
  GstAudioEncoder *encoder = data->encoder;
  GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (encoder);
  GstBuffer *outbuf = data->outbuf;
  const GstMetaInfo *info = (*meta)->info;
  gboolean do_copy = FALSE;

  if (gst_meta_api_type_has_tag (info->api, _gst_meta_tag_memory)) {
    /* never call the transform_meta with memory specific metadata */
    GST_DEBUG_OBJECT (encoder, "not copying memory specific metadata %s",
        g_type_name (info->api));
    do_copy = FALSE;
  } else if (klass->transform_meta) {
    do_copy = klass->transform_meta (encoder, outbuf, *meta, inbuf);
    GST_DEBUG_OBJECT (encoder, "transformed metadata %s: copy: %d",
        g_type_name (info->api), do_copy);
  }

  /* we only copy metadata when the subclass implemented a transform_meta
   * function and when it returns %TRUE */
  if (do_copy) {
    GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
    GST_DEBUG_OBJECT (encoder, "copy metadata %s", g_type_name (info->api));
    /* simply copy then */
    info->transform_func (outbuf, *meta, inbuf,
        _gst_meta_transform_copy, &copy_data);
  }
  return TRUE;
}

/**
 * gst_audio_encoder_finish_frame:
 * @enc: a #GstAudioEncoder
 * @buffer: encoded data
 * @samples: number of samples (per channel) represented by encoded data
 *
 * Collects encoded data and pushes encoded data downstream.
 * Source pad caps must be set when this is called.
 *
 * If @samples < 0, then best estimate is all samples provided to encoder
 * (subclass) so far.  @buf may be NULL, in which case next number of @samples
 * are considered discarded, e.g. as a result of discontinuous transmission,
 * and a discontinuity is marked.
 *
 * Note that samples received in gst_audio_encoder_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_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf,
    gint samples)
{
  GstAudioEncoderClass *klass;
  GstAudioEncoderPrivate *priv;
  GstAudioEncoderContext *ctx;
  GstFlowReturn ret = GST_FLOW_OK;
  gboolean needs_reconfigure = FALSE;
  GstBuffer *inbuf = NULL;

  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
  priv = enc->priv;
  ctx = &enc->priv->ctx;

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

  /* subclass should know what it is producing by now */
  if (!ctx->caps)
    goto no_caps;

  GST_AUDIO_ENCODER_STREAM_LOCK (enc);

  GST_LOG_OBJECT (enc,
      "accepting %" G_GSIZE_FORMAT " bytes encoded data as %d samples",
      buf ? gst_buffer_get_size (buf) : -1, samples);

  needs_reconfigure = gst_pad_check_reconfigure (enc->srcpad);
  if (G_UNLIKELY (ctx->output_caps_changed || needs_reconfigure)) {
    if (!gst_audio_encoder_negotiate_unlocked (enc)) {
      gst_pad_mark_reconfigure (enc->srcpad);
      if (GST_PAD_IS_FLUSHING (enc->srcpad))
        ret = GST_FLOW_FLUSHING;
      else
        ret = GST_FLOW_NOT_NEGOTIATED;
      if (buf)
        gst_buffer_unref (buf);
      goto exit;
    }
  }

  /* mark subclass still alive and providing */
  if (G_LIKELY (buf))
    priv->got_data = TRUE;

  gst_audio_encoder_push_pending_events (enc);

  /* send after pending events, which likely includes segment event */
  gst_audio_encoder_check_and_push_pending_tags (enc);

  /* remove corresponding samples from input */
  if (samples < 0)
    samples = (enc->priv->offset / ctx->info.bpf);

  if (G_LIKELY (samples)) {
    /* track upstream ts if so configured */
    if (!enc->priv->perfect_ts) {
      guint64 ts, distance;

      ts = gst_adapter_prev_pts (priv->adapter, &distance);
      g_assert (distance % ctx->info.bpf == 0);
      distance /= ctx->info.bpf;
      GST_LOG_OBJECT (enc, "%" G_GUINT64_FORMAT " samples past prev_ts %"
          GST_TIME_FORMAT, distance, GST_TIME_ARGS (ts));
      GST_LOG_OBJECT (enc, "%" G_GUINT64_FORMAT " samples past base_ts %"
          GST_TIME_FORMAT, priv->samples, GST_TIME_ARGS (priv->base_ts));
      /* when draining adapter might be empty and no ts to offer */
      if (GST_CLOCK_TIME_IS_VALID (ts) && ts != priv->base_ts) {
        GstClockTimeDiff diff;
        GstClockTime old_ts, next_ts;

        /* passed into another buffer;
         * mild check for discontinuity and only mark if so */
        next_ts = ts +
            gst_util_uint64_scale (distance, GST_SECOND, ctx->info.rate);
        old_ts = priv->base_ts +
            gst_util_uint64_scale (priv->samples, GST_SECOND, ctx->info.rate);
        diff = GST_CLOCK_DIFF (next_ts, old_ts);
        GST_LOG_OBJECT (enc, "ts diff %d ms", (gint) (diff / GST_MSECOND));
        /* only mark discontinuity if beyond tolerance */
        if (G_UNLIKELY (diff < -enc->priv->tolerance ||
                diff > enc->priv->tolerance)) {
          GST_DEBUG_OBJECT (enc, "marked discont");
          priv->discont = TRUE;
        }
        if (diff > GST_SECOND / ctx->info.rate / 2 ||
            diff < -GST_SECOND / ctx->info.rate / 2) {
          GST_LOG_OBJECT (enc, "new upstream ts %" GST_TIME_FORMAT
              " at distance %" G_GUINT64_FORMAT, GST_TIME_ARGS (ts), distance);
          /* re-sync to upstream ts */
          priv->base_ts = ts;
          priv->samples = distance;
        } else {
          GST_LOG_OBJECT (enc, "new upstream ts only introduces jitter");
        }
      }
    }
    /* advance sample view */
    if (G_UNLIKELY (samples * ctx->info.bpf > priv->offset)) {
      guint avail = gst_adapter_available (priv->adapter);

      if (G_LIKELY (!priv->force)) {
        /* we should have received EOS to enable force */
        goto overflow;
      } else {
        priv->offset = 0;
        if (avail > 0 && samples * ctx->info.bpf >= avail) {
          inbuf = gst_adapter_take_buffer_fast (priv->adapter, avail);
          gst_adapter_clear (priv->adapter);
        } else if (avail > 0) {
          inbuf =
              gst_adapter_take_buffer_fast (priv->adapter,
              samples * ctx->info.bpf);
        }
      }
    } else {
      guint avail = gst_adapter_available (priv->adapter);

      if (avail > 0) {
        inbuf =
            gst_adapter_take_buffer_fast (priv->adapter,
            samples * ctx->info.bpf);
      }
      priv->offset -= samples * ctx->info.bpf;
      /* avoid subsequent stray prev_ts */
      if (G_UNLIKELY (gst_adapter_available (priv->adapter) == 0))
        gst_adapter_clear (priv->adapter);
    }
    /* sample count advanced below after buffer handling */
  }

  /* collect output */
  if (G_LIKELY (buf)) {
    gsize size;

    /* Pushing headers first */
    if (G_UNLIKELY (priv->ctx.new_headers)) {
      GList *tmp;

      GST_DEBUG_OBJECT (enc, "Sending headers");

      for (tmp = priv->ctx.headers; tmp; tmp = tmp->next) {
        GstBuffer *tmpbuf = gst_buffer_ref (tmp->data);

        tmpbuf = gst_buffer_make_writable (tmpbuf);
        size = gst_buffer_get_size (tmpbuf);

        if (G_UNLIKELY (priv->discont)) {
          GST_LOG_OBJECT (enc, "marking discont");
          GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
          priv->discont = FALSE;
        }

        /* Ogg codecs like Vorbis use offset/offset-end in a special
         * way and both should be 0 for these codecs */
        if (priv->base_gp >= 0) {
          GST_BUFFER_OFFSET (tmpbuf) = 0;
          GST_BUFFER_OFFSET_END (tmpbuf) = 0;
        } else {
          GST_BUFFER_OFFSET (tmpbuf) = priv->bytes_out;
          GST_BUFFER_OFFSET_END (tmpbuf) = priv->bytes_out + size;
        }

        GST_OBJECT_LOCK (enc);
        priv->bytes_out += size;
        GST_OBJECT_UNLOCK (enc);

        ret = gst_pad_push (enc->srcpad, tmpbuf);
        if (ret != GST_FLOW_OK) {
          GST_WARNING_OBJECT (enc, "pushing header returned %s",
            gst_flow_get_name (ret));
          goto exit;
        }
      }
      priv->ctx.new_headers = FALSE;
    }

    size = gst_buffer_get_size (buf);

    GST_LOG_OBJECT (enc, "taking %" G_GSIZE_FORMAT " bytes for output", size);
    buf = gst_buffer_make_writable (buf);

    /* decorate */
    if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
      /* FIXME ? lookahead could lead to weird ts and duration ?
       * (particularly if not in perfect mode) */
      /* mind sample rounding and produce perfect output */
      GST_BUFFER_TIMESTAMP (buf) = priv->base_ts +
          gst_util_uint64_scale (priv->samples - ctx->lookahead, GST_SECOND,
          ctx->info.rate);
      GST_BUFFER_DTS (buf) = GST_BUFFER_TIMESTAMP (buf);
      GST_DEBUG_OBJECT (enc, "out samples %d", samples);
      if (G_LIKELY (samples > 0)) {
        priv->samples += samples;
        GST_BUFFER_DURATION (buf) = priv->base_ts +
            gst_util_uint64_scale (priv->samples - ctx->lookahead, GST_SECOND,
            ctx->info.rate) - GST_BUFFER_TIMESTAMP (buf);
        priv->last_duration = GST_BUFFER_DURATION (buf);
      } else {
        /* duration forecast in case of handling remainder;
         * the last one is probably like the previous one ... */
        GST_BUFFER_DURATION (buf) = priv->last_duration;
      }
      if (priv->base_gp >= 0) {
        /* pamper oggmux */
        /* FIXME: in longer run, muxer should take care of this ... */
        /* offset_end = granulepos for ogg muxer */
        GST_BUFFER_OFFSET_END (buf) = priv->base_gp + priv->samples -
            enc->priv->ctx.lookahead;
        /* offset = timestamp corresponding to granulepos for ogg muxer */
        GST_BUFFER_OFFSET (buf) =
            GST_FRAMES_TO_CLOCK_TIME (GST_BUFFER_OFFSET_END (buf),
            ctx->info.rate);
      } else {
        GST_BUFFER_OFFSET (buf) = priv->bytes_out;
        GST_BUFFER_OFFSET_END (buf) = priv->bytes_out + size;
      }
    }

    if (klass->transform_meta) {
      if (G_LIKELY (inbuf)) {
        CopyMetaData data;

        data.encoder = enc;
        data.outbuf = buf;
        gst_buffer_foreach_meta (inbuf, foreach_metadata, &data);
      } else {
        GST_WARNING_OBJECT (enc,
            "Can't copy metadata because input buffer disappeared");
      }
    }

    GST_OBJECT_LOCK (enc);
    priv->bytes_out += size;
    GST_OBJECT_UNLOCK (enc);

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

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

        if (buf)
          gst_buffer_unref (buf);
        goto exit;
      }
    }

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

    ret = gst_pad_push (enc->srcpad, buf);
    GST_LOG_OBJECT (enc, "buffer pushed: %s", gst_flow_get_name (ret));
  } else {
    /* merely advance samples, most work for that already done above */
    priv->samples += samples;
  }

exit:
  if (inbuf)
    gst_buffer_unref (inbuf);

  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

  return ret;

  /* ERRORS */
no_caps:
  {
    GST_ELEMENT_ERROR (enc, STREAM, ENCODE, ("no caps set"), (NULL));
    if (buf)
      gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
overflow:
  {
    GST_ELEMENT_ERROR (enc, STREAM, ENCODE,
        ("received more encoded samples %d than provided %d as inputs",
            samples, priv->offset / ctx->info.bpf), (NULL));
    if (buf)
      gst_buffer_unref (buf);
    ret = GST_FLOW_ERROR;
    /* no way we can let this pass */
    g_assert_not_reached ();
    /* really no way */
    goto exit;
  }
}

 /* adapter tracking idea:
  * - start of adapter corresponds with what has already been encoded
  * (i.e. really returned by encoder subclass)
  * - start + offset is what needs to be fed to subclass next */
static GstFlowReturn
gst_audio_encoder_push_buffers (GstAudioEncoder * enc, gboolean force)
{
  GstAudioEncoderClass *klass;
  GstAudioEncoderPrivate *priv;
  GstAudioEncoderContext *ctx;
  gint av, need;
  GstBuffer *buf;
  GstFlowReturn ret = GST_FLOW_OK;

  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

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

  priv = enc->priv;
  ctx = &enc->priv->ctx;

  while (ret == GST_FLOW_OK) {

    buf = NULL;
    av = gst_adapter_available (priv->adapter);

    g_assert (priv->offset <= av);
    av -= priv->offset;

    need =
        ctx->frame_samples_min >
        0 ? ctx->frame_samples_min * ctx->info.bpf : av;
    GST_LOG_OBJECT (enc, "available: %d, needed: %d, force: %d", av, need,
        force);

    if ((need > av) || !av) {
      if (G_UNLIKELY (force)) {
        priv->force = TRUE;
        need = av;
      } else {
        break;
      }
    } else {
      priv->force = FALSE;
    }

    if (ctx->frame_samples_max > 0)
      need = MIN (av, ctx->frame_samples_max * ctx->info.bpf);

    if (ctx->frame_samples_min == ctx->frame_samples_max) {
      /* if we have some extra metadata,
       * provide for integer multiple of frames to allow for better granularity
       * of processing */
      if (ctx->frame_samples_min > 0 && need) {
        if (ctx->frame_max > 1)
          need = need * MIN ((av / need), ctx->frame_max);
        else if (ctx->frame_max == 0)
          need = need * (av / need);
      }
    }

    priv->got_data = FALSE;
    if (G_LIKELY (need)) {
      const guint8 *data;

      data = gst_adapter_map (priv->adapter, priv->offset + need);
      buf =
          gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
          (gpointer) data, priv->offset + need, priv->offset, need, NULL, NULL);
    } else if (!priv->drainable) {
      GST_DEBUG_OBJECT (enc, "non-drainable and no more data");
      goto finish;
    }

    GST_LOG_OBJECT (enc, "providing subclass with %d bytes at offset %d",
        need, priv->offset);

    /* mark this already as consumed,
     * which it should be when subclass gives us data in exchange for samples */
    priv->offset += need;
    GST_OBJECT_LOCK (enc);
    priv->samples_in += need / ctx->info.bpf;
    GST_OBJECT_UNLOCK (enc);

    /* subclass might not want to be bothered with leftover data,
     * so take care of that here if so, otherwise pass along */
    if (G_UNLIKELY (priv->force && priv->hard_min && buf)) {
      GST_DEBUG_OBJECT (enc, "bypassing subclass with leftover");
      ret = gst_audio_encoder_finish_frame (enc, NULL, -1);
    } else {
      ret = klass->handle_frame (enc, buf);
    }

    if (G_LIKELY (buf)) {
      gst_buffer_unref (buf);
      gst_adapter_unmap (priv->adapter);
    }

  finish:
    /* no data to feed, no leftover provided, then bail out */
    if (G_UNLIKELY (!buf && !priv->got_data)) {
      priv->drained = TRUE;
      GST_LOG_OBJECT (enc, "no more data drained from subclass");
      break;
    }
  }

  return ret;
}

static GstFlowReturn
gst_audio_encoder_drain (GstAudioEncoder * enc)
{
  GST_DEBUG_OBJECT (enc, "draining");
  if (enc->priv->drained)
    return GST_FLOW_OK;
  else {
    GST_DEBUG_OBJECT (enc, "... really");
    return gst_audio_encoder_push_buffers (enc, TRUE);
  }
}

static void
gst_audio_encoder_set_base_gp (GstAudioEncoder * enc)
{
  GstClockTime ts;

  if (!enc->priv->granule)
    return;

  /* use running time for granule */
  /* incoming data is clipped, so a valid input should yield a valid output */
  ts = gst_segment_to_running_time (&enc->input_segment, GST_FORMAT_TIME,
      enc->priv->base_ts);
  if (GST_CLOCK_TIME_IS_VALID (ts)) {
    enc->priv->base_gp =
        GST_CLOCK_TIME_TO_FRAMES (enc->priv->base_ts, enc->priv->ctx.info.rate);
    GST_DEBUG_OBJECT (enc, "new base gp %" G_GINT64_FORMAT, enc->priv->base_gp);
  } else {
    /* should reasonably have a valid base,
     * otherwise start at 0 if we did not already start there earlier */
    if (enc->priv->base_gp < 0) {
      enc->priv->base_gp = 0;
      GST_DEBUG_OBJECT (enc, "new base gp %" G_GINT64_FORMAT,
          enc->priv->base_gp);
    }
  }
}

static GstFlowReturn
gst_audio_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstAudioEncoder *enc;
  GstAudioEncoderPrivate *priv;
  GstAudioEncoderContext *ctx;
  GstFlowReturn ret = GST_FLOW_OK;
  gboolean discont;
  gsize size;

  enc = GST_AUDIO_ENCODER (parent);

  priv = enc->priv;
  ctx = &enc->priv->ctx;

  GST_AUDIO_ENCODER_STREAM_LOCK (enc);

  if (G_UNLIKELY (priv->do_caps)) {
    GstCaps *caps = gst_pad_get_current_caps (enc->sinkpad);
    if (!caps)
      goto not_negotiated;
    if (!gst_audio_encoder_sink_setcaps (enc, caps)) {
      gst_caps_unref (caps);
      goto not_negotiated;
    }
    gst_caps_unref (caps);
    priv->do_caps = FALSE;
  }

  /* should know what is coming by now */
  if (!ctx->info.bpf)
    goto not_negotiated;

  size = gst_buffer_get_size (buffer);

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

  /* input shoud be whole number of sample frames */
  if (size % ctx->info.bpf)
    goto wrong_buffer;

#ifndef GST_DISABLE_GST_DEBUG
  {
    GstClockTime duration;
    GstClockTimeDiff diff;

    /* verify buffer duration */
    duration = gst_util_uint64_scale (size, GST_SECOND,
        ctx->info.rate * ctx->info.bpf);
    diff = GST_CLOCK_DIFF (duration, GST_BUFFER_DURATION (buffer));
    if (GST_BUFFER_DURATION (buffer) != GST_CLOCK_TIME_NONE &&
        (diff > GST_SECOND / ctx->info.rate / 2 ||
            diff < -GST_SECOND / ctx->info.rate / 2)) {
      GST_DEBUG_OBJECT (enc, "incoming buffer had incorrect duration %"
          GST_TIME_FORMAT ", expected duration %" GST_TIME_FORMAT,
          GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)),
          GST_TIME_ARGS (duration));
    }
  }
#endif

  discont = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT);
  if (G_UNLIKELY (discont)) {
    GST_LOG_OBJECT (buffer, "marked discont");
    enc->priv->discont = discont;
  }

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

  size = gst_buffer_get_size (buffer);

  GST_LOG_OBJECT (enc,
      "buffer after segment clipping has size %" G_GSIZE_FORMAT " with ts %"
      GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT, size,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));

  if (!GST_CLOCK_TIME_IS_VALID (priv->base_ts)) {
    priv->base_ts = GST_BUFFER_TIMESTAMP (buffer);
    GST_DEBUG_OBJECT (enc, "new base ts %" GST_TIME_FORMAT,
        GST_TIME_ARGS (priv->base_ts));
    gst_audio_encoder_set_base_gp (enc);
  }

  /* check for continuity;
   * checked elsewhere in non-perfect case */
  if (enc->priv->perfect_ts) {
    GstClockTimeDiff diff = 0;
    GstClockTime next_ts = 0;

    if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
        GST_CLOCK_TIME_IS_VALID (priv->base_ts)) {
      guint64 samples;

      samples = priv->samples +
          gst_adapter_available (priv->adapter) / ctx->info.bpf;
      next_ts = priv->base_ts +
          gst_util_uint64_scale (samples, GST_SECOND, ctx->info.rate);
      GST_LOG_OBJECT (enc, "buffer is %" G_GUINT64_FORMAT
          " samples past base_ts %" GST_TIME_FORMAT
          ", expected ts %" GST_TIME_FORMAT, samples,
          GST_TIME_ARGS (priv->base_ts), GST_TIME_ARGS (next_ts));
      diff = GST_CLOCK_DIFF (next_ts, GST_BUFFER_TIMESTAMP (buffer));
      GST_LOG_OBJECT (enc, "ts diff %d ms", (gint) (diff / GST_MSECOND));
      /* if within tolerance,
       * discard buffer ts and carry on producing perfect stream,
       * otherwise clip or resync to ts */
      if (G_UNLIKELY (diff < -enc->priv->tolerance ||
              diff > enc->priv->tolerance)) {
        GST_DEBUG_OBJECT (enc, "marked discont");
        discont = TRUE;
      }
    }

    /* do some fancy tweaking in hard resync case */
    if (discont && enc->priv->hard_resync) {
      if (diff < 0) {
        guint64 diff_bytes;

        GST_WARNING_OBJECT (enc, "Buffer is older than expected ts %"
            GST_TIME_FORMAT ".  Clipping buffer", GST_TIME_ARGS (next_ts));

        diff_bytes =
            GST_CLOCK_TIME_TO_FRAMES (-diff, ctx->info.rate) * ctx->info.bpf;
        if (diff_bytes >= size) {
          gst_buffer_unref (buffer);
          goto done;
        }
        buffer = gst_buffer_make_writable (buffer);
        gst_buffer_resize (buffer, diff_bytes, size - diff_bytes);

        GST_BUFFER_TIMESTAMP (buffer) += diff;
        /* care even less about duration after this */
      } else {
        /* drain stuff prior to resync */
        gst_audio_encoder_drain (enc);
      }
    }
    if (discont) {
      /* now re-sync ts */
      priv->base_ts += diff;
      gst_audio_encoder_set_base_gp (enc);
      priv->discont |= discont;
    }
  }

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

  ret = gst_audio_encoder_push_buffers (enc, FALSE);

done:
  GST_LOG_OBJECT (enc, "chain leaving");

  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

  return ret;

  /* ERRORS */
not_negotiated:
  {
    GST_ELEMENT_ERROR (enc, CORE, NEGOTIATION, (NULL),
        ("encoder not initialized"));
    gst_buffer_unref (buffer);
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
wrong_buffer:
  {
    GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
        ("buffer size %" G_GSIZE_FORMAT " not a multiple of %d",
            gst_buffer_get_size (buffer), ctx->info.bpf));
    gst_buffer_unref (buffer);
    ret = GST_FLOW_ERROR;
    goto done;
  }
}

static gboolean
gst_audio_encoder_sink_setcaps (GstAudioEncoder * enc, GstCaps * caps)
{
  GstAudioEncoderClass *klass;
  GstAudioEncoderContext *ctx;
  GstAudioInfo state;
  gboolean res = TRUE;
  guint old_rate;

  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

  /* subclass must do something here ... */
  g_return_val_if_fail (klass->set_format != NULL, FALSE);

  ctx = &enc->priv->ctx;

  GST_AUDIO_ENCODER_STREAM_LOCK (enc);

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

  if (!gst_caps_is_fixed (caps))
    goto refuse_caps;

  if (enc->priv->ctx.input_caps
      && gst_caps_is_equal (enc->priv->ctx.input_caps, caps))
    goto same_caps;

  if (!gst_audio_info_from_caps (&state, caps))
    goto refuse_caps;

  if (enc->priv->ctx.input_caps && gst_audio_info_is_equal (&state, &ctx->info))
    goto same_caps;

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

  /* drain any pending old data stuff */
  gst_audio_encoder_drain (enc);

  /* context defaults */
  /* FIXME 2.0: This is quite unexpected behaviour. We should never
   * just reset *settings* of a subclass inside the base class */
  enc->priv->ctx.frame_samples_min = 0;
  enc->priv->ctx.frame_samples_max = 0;
  enc->priv->ctx.frame_max = 0;
  enc->priv->ctx.lookahead = 0;

  if (klass->set_format)
    res = klass->set_format (enc, &state);

  if (res) {
    GST_OBJECT_LOCK (enc);
    ctx->info = state;
    gst_caps_replace (&enc->priv->ctx.input_caps, caps);
    GST_OBJECT_UNLOCK (enc);
  } else {
    /* invalidate state to ensure no casual carrying on */
    GST_DEBUG_OBJECT (enc, "subclass did not accept format");
    gst_audio_info_init (&state);
    goto exit;
  }

exit:

  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

  return res;

same_caps:
  {
    GST_DEBUG_OBJECT (enc, "new audio format identical to configured format");
    goto exit;
  }

  /* ERRORS */
refuse_caps:
  {
    GST_WARNING_OBJECT (enc, "rejected caps %" GST_PTR_FORMAT, caps);
    goto exit;
  }
}


/**
 * gst_audio_encoder_proxy_getcaps:
 * @enc: a #GstAudioEncoder
 * @caps: (allow-none): initial caps
 * @filter: (allow-none): filter caps
 *
 * Returns caps that express @caps (or sink template caps if @caps == NULL)
 * restricted to channel/rate combinations supported by downstream elements
 * (e.g. muxers).
 *
 * Returns: (transfer full): a #GstCaps owned by caller
 */
GstCaps *
gst_audio_encoder_proxy_getcaps (GstAudioEncoder * enc, GstCaps * caps,
    GstCaps * filter)
{
  return __gst_audio_element_proxy_getcaps (GST_ELEMENT_CAST (enc),
      GST_AUDIO_ENCODER_SINK_PAD (enc), GST_AUDIO_ENCODER_SRC_PAD (enc),
      caps, filter);
}

static GstCaps *
gst_audio_encoder_getcaps_default (GstAudioEncoder * enc, GstCaps * filter)
{
  GstCaps *caps;

  caps = gst_audio_encoder_proxy_getcaps (enc, NULL, filter);
  GST_LOG_OBJECT (enc, "returning caps %" GST_PTR_FORMAT, caps);

  return caps;
}

static GList *
_flush_events (GstPad * pad, GList * events)
{
  GList *tmp;

  for (tmp = events; tmp; tmp = tmp->next) {
    if (GST_EVENT_TYPE (tmp->data) != GST_EVENT_EOS &&
        GST_EVENT_TYPE (tmp->data) != GST_EVENT_SEGMENT &&
        GST_EVENT_IS_STICKY (tmp->data)) {
      gst_pad_store_sticky_event (pad, GST_EVENT_CAST (tmp->data));
    }
    gst_event_unref (tmp->data);
  }
  g_list_free (events);

  return NULL;
}

static gboolean
gst_audio_encoder_sink_event_default (GstAudioEncoder * enc, GstEvent * event)
{
  GstAudioEncoderClass *klass;
  gboolean res;

  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      GstSegment seg;

      gst_event_copy_segment (event, &seg);

      if (seg.format == GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (enc, "received TIME SEGMENT %" GST_SEGMENT_FORMAT,
            &seg);
      } else {
        GST_DEBUG_OBJECT (enc, "received SEGMENT %" GST_SEGMENT_FORMAT, &seg);
        GST_DEBUG_OBJECT (enc, "unsupported format; ignoring");
        res = TRUE;
        break;
      }

      GST_AUDIO_ENCODER_STREAM_LOCK (enc);
      /* finish current segment */
      gst_audio_encoder_drain (enc);
      /* reset partially for new segment */
      gst_audio_encoder_reset (enc, FALSE);
      /* and follow along with segment */
      enc->input_segment = seg;

      enc->priv->pending_events =
          g_list_append (enc->priv->pending_events, event);
      GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

      res = TRUE;
      break;
    }

    case GST_EVENT_FLUSH_START:
      res = gst_audio_encoder_push_event (enc, event);
      break;

    case GST_EVENT_FLUSH_STOP:
      GST_AUDIO_ENCODER_STREAM_LOCK (enc);
      /* discard any pending stuff */
      /* TODO route through drain ?? */
      if (!enc->priv->drained && klass->flush)
        klass->flush (enc);
      /* and get (re)set for the sequel */
      gst_audio_encoder_reset (enc, FALSE);

      enc->priv->pending_events = _flush_events (enc->srcpad,
          enc->priv->pending_events);
      GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

      res = gst_audio_encoder_push_event (enc, event);
      break;

    case GST_EVENT_EOS:
      GST_AUDIO_ENCODER_STREAM_LOCK (enc);
      gst_audio_encoder_drain (enc);

      /* check for pending events and tags */
      gst_audio_encoder_push_pending_events (enc);
      gst_audio_encoder_check_and_push_pending_tags (enc);

      GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

      /* forward immediately because no buffer or serialized event
       * will come after EOS and nothing could trigger another
       * _finish_frame() call. */
      res = gst_audio_encoder_push_event (enc, event);
      break;

    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      enc->priv->do_caps = TRUE;
      res = TRUE;
      gst_event_unref (event);
      break;
    }

    case GST_EVENT_STREAM_START:
    {
      GST_AUDIO_ENCODER_STREAM_LOCK (enc);
      /* Flush upstream tags after a STREAM_START */
      GST_DEBUG_OBJECT (enc, "received STREAM_START. Clearing taglist");
      if (enc->priv->upstream_tags) {
        gst_tag_list_unref (enc->priv->upstream_tags);
        enc->priv->upstream_tags = NULL;
        enc->priv->tags_changed = TRUE;
      }
      GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
      res = gst_audio_encoder_push_event (enc, 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_ENCODER_STREAM_LOCK (enc);
        if (enc->priv->upstream_tags != tags) {
          tags = gst_tag_list_copy (tags);

          /* FIXME: make generic based on GST_TAG_FLAG_ENCODED */
          gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
          gst_tag_list_remove_tag (tags, GST_TAG_AUDIO_CODEC);
          gst_tag_list_remove_tag (tags, GST_TAG_VIDEO_CODEC);
          gst_tag_list_remove_tag (tags, GST_TAG_SUBTITLE_CODEC);
          gst_tag_list_remove_tag (tags, GST_TAG_CONTAINER_FORMAT);
          gst_tag_list_remove_tag (tags, GST_TAG_BITRATE);
          gst_tag_list_remove_tag (tags, GST_TAG_NOMINAL_BITRATE);
          gst_tag_list_remove_tag (tags, GST_TAG_MAXIMUM_BITRATE);
          gst_tag_list_remove_tag (tags, GST_TAG_MINIMUM_BITRATE);
          gst_tag_list_remove_tag (tags, GST_TAG_ENCODER);
          gst_tag_list_remove_tag (tags, GST_TAG_ENCODER_VERSION);

          if (enc->priv->upstream_tags)
            gst_tag_list_unref (enc->priv->upstream_tags);
          enc->priv->upstream_tags = tags;
          GST_INFO_OBJECT (enc, "upstream stream tags: %" GST_PTR_FORMAT, tags);
        }
        gst_event_unref (event);
        event = gst_audio_encoder_create_merged_tags_event (enc);
        GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

        /* No tags, go out of here instead of fall through */
        if (!event) {
          res = TRUE;
          break;
        }
      }
      /* fall through */
    }
    default:
      /* Forward non-serialized events immediately. */
      if (!GST_EVENT_IS_SERIALIZED (event)) {
        res =
            gst_pad_event_default (enc->sinkpad, GST_OBJECT_CAST (enc), event);
      } else {
        GST_AUDIO_ENCODER_STREAM_LOCK (enc);
        enc->priv->pending_events =
            g_list_append (enc->priv->pending_events, event);
        GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
        res = TRUE;
      }
      break;
  }
  return res;
}

static gboolean
gst_audio_encoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstAudioEncoder *enc;
  GstAudioEncoderClass *klass;
  gboolean ret;

  enc = GST_AUDIO_ENCODER (parent);
  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

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

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

  GST_DEBUG_OBJECT (enc, "event result %d", ret);

  return ret;
}

static gboolean
gst_audio_encoder_sink_query_default (GstAudioEncoder * enc, GstQuery * query)
{
  GstPad *pad = GST_AUDIO_ENCODER_SINK_PAD (enc);
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    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);
      GST_OBJECT_LOCK (enc);
      res = gst_audio_info_convert (&enc->priv->ctx.info,
          src_fmt, src_val, dest_fmt, &dest_val);
      GST_OBJECT_UNLOCK (enc);
      if (!res)
        goto error;
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      res = TRUE;
      break;
    }
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;
      GstAudioEncoderClass *klass;

      gst_query_parse_caps (query, &filter);

      klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
      if (klass->getcaps) {
        caps = klass->getcaps (enc, filter);
        gst_query_set_caps_result (query, caps);
        gst_caps_unref (caps);
        res = TRUE;
      }
      break;
    }
    case GST_QUERY_ALLOCATION:
    {
      GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

      if (klass->propose_allocation)
        res = klass->propose_allocation (enc, query);
      break;
    }
    default:
      res = gst_pad_query_default (pad, GST_OBJECT (enc), query);
      break;
  }

error:
  return res;
}

static gboolean
gst_audio_encoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstAudioEncoder *encoder;
  GstAudioEncoderClass *encoder_class;
  gboolean ret = FALSE;

  encoder = GST_AUDIO_ENCODER (parent);
  encoder_class = GST_AUDIO_ENCODER_GET_CLASS (encoder);

  GST_DEBUG_OBJECT (encoder, "received query %d, %s", GST_QUERY_TYPE (query),
      GST_QUERY_TYPE_NAME (query));

  if (encoder_class->sink_query)
    ret = encoder_class->sink_query (encoder, query);

  return ret;
}

static gboolean
gst_audio_encoder_src_event_default (GstAudioEncoder * enc, GstEvent * event)
{
  gboolean res;

  switch (GST_EVENT_TYPE (event)) {
    default:
      res = gst_pad_event_default (enc->srcpad, GST_OBJECT_CAST (enc), event);
      break;
  }
  return res;
}

static gboolean
gst_audio_encoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstAudioEncoder *enc;
  GstAudioEncoderClass *klass;
  gboolean ret;

  enc = GST_AUDIO_ENCODER (parent);
  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

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

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

  return ret;
}

static gboolean
gst_audio_encoder_decide_allocation_default (GstAudioEncoder * enc,
    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_encoder_propose_allocation_default (GstAudioEncoder * enc,
    GstQuery * query)
{
  return TRUE;
}

/* FIXME ? are any of these queries (other than latency) an encoder'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_encoder_src_query_default (GstAudioEncoder * enc, GstQuery * query)
{
  GstPad *pad = GST_AUDIO_ENCODER_SRC_PAD (enc);
  gboolean res = FALSE;

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

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat fmt, req_fmt;
      gint64 pos, val;

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

      gst_query_parse_position (query, &req_fmt, NULL);
      fmt = GST_FORMAT_TIME;
      if (!(res = gst_pad_peer_query_position (enc->sinkpad, fmt, &pos)))
        break;

      if ((res =
              gst_pad_peer_query_convert (enc->sinkpad, fmt, pos, req_fmt,
                  &val))) {
        gst_query_set_position (query, req_fmt, val);
      }
      break;
    }
    case GST_QUERY_DURATION:
    {
      GstFormat fmt, req_fmt;
      gint64 dur, val;

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

      gst_query_parse_duration (query, &req_fmt, NULL);
      fmt = GST_FORMAT_TIME;
      if (!(res = gst_pad_peer_query_duration (enc->sinkpad, fmt, &dur)))
        break;

      if ((res =
              gst_pad_peer_query_convert (enc->sinkpad, fmt, dur, req_fmt,
                  &val))) {
        gst_query_set_duration (query, req_fmt, val);
      }
      break;
    }
    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);
      GST_OBJECT_LOCK (enc);
      res = __gst_audio_encoded_audio_convert (&enc->priv->ctx.info,
          enc->priv->bytes_out, enc->priv->samples_in, src_fmt, src_val,
          &dest_fmt, &dest_val);
      GST_OBJECT_UNLOCK (enc);
      if (!res)
        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 (enc->sinkpad, query))) {
        gboolean live;
        GstClockTime min_latency, max_latency;

        gst_query_parse_latency (query, &live, &min_latency, &max_latency);
        GST_DEBUG_OBJECT (enc, "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 (enc);
        /* add our latency */
        min_latency += enc->priv->ctx.min_latency;
        if (max_latency == -1 || enc->priv->ctx.max_latency == -1)
          max_latency = -1;
        else
          max_latency += enc->priv->ctx.max_latency;
        GST_OBJECT_UNLOCK (enc);

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

  return res;
}

static gboolean
gst_audio_encoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstAudioEncoder *encoder;
  GstAudioEncoderClass *encoder_class;
  gboolean ret = FALSE;

  encoder = GST_AUDIO_ENCODER (parent);
  encoder_class = GST_AUDIO_ENCODER_GET_CLASS (encoder);

  GST_DEBUG_OBJECT (encoder, "received query %d, %s", GST_QUERY_TYPE (query),
      GST_QUERY_TYPE_NAME (query));

  if (encoder_class->src_query)
    ret = encoder_class->src_query (encoder, query);

  return ret;
}


static void
gst_audio_encoder_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioEncoder *enc;

  enc = GST_AUDIO_ENCODER (object);

  switch (prop_id) {
    case PROP_PERFECT_TS:
      if (enc->priv->granule && !g_value_get_boolean (value))
        GST_WARNING_OBJECT (enc, "perfect-timestamp can not be set FALSE "
            "while granule handling is enabled");
      else
        enc->priv->perfect_ts = g_value_get_boolean (value);
      break;
    case PROP_HARD_RESYNC:
      enc->priv->hard_resync = g_value_get_boolean (value);
      break;
    case PROP_TOLERANCE:
      enc->priv->tolerance = g_value_get_int64 (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_audio_encoder_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioEncoder *enc;

  enc = GST_AUDIO_ENCODER (object);

  switch (prop_id) {
    case PROP_PERFECT_TS:
      g_value_set_boolean (value, enc->priv->perfect_ts);
      break;
    case PROP_GRANULE:
      g_value_set_boolean (value, enc->priv->granule);
      break;
    case PROP_HARD_RESYNC:
      g_value_set_boolean (value, enc->priv->hard_resync);
      break;
    case PROP_TOLERANCE:
      g_value_set_int64 (value, enc->priv->tolerance);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_audio_encoder_activate (GstAudioEncoder * enc, gboolean active)
{
  GstAudioEncoderClass *klass;
  gboolean result = TRUE;

  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

  g_return_val_if_fail (!enc->priv->granule || enc->priv->perfect_ts, FALSE);

  GST_DEBUG_OBJECT (enc, "activate %d", active);

  if (active) {
    /* arrange clean state */
    gst_audio_encoder_reset (enc, TRUE);

    if (!enc->priv->active && klass->start)
      result = klass->start (enc);
  } else {
    /* We must make sure streaming has finished before resetting things
     * and calling the ::stop vfunc */
    GST_PAD_STREAM_LOCK (enc->sinkpad);
    GST_PAD_STREAM_UNLOCK (enc->sinkpad);

    if (enc->priv->active && klass->stop)
      result = klass->stop (enc);

    /* clean up */
    gst_audio_encoder_reset (enc, TRUE);
  }
  GST_DEBUG_OBJECT (enc, "activate return: %d", result);
  return result;
}


static gboolean
gst_audio_encoder_sink_activate_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean result = TRUE;
  GstAudioEncoder *enc;

  enc = GST_AUDIO_ENCODER (parent);

  GST_DEBUG_OBJECT (enc, "sink activate push %d", active);

  result = gst_audio_encoder_activate (enc, active);

  if (result)
    enc->priv->active = active;

  GST_DEBUG_OBJECT (enc, "sink activate push return: %d", result);

  return result;
}

/**
 * gst_audio_encoder_get_audio_info:
 * @enc: a #GstAudioEncoder
 *
 * Returns: a #GstAudioInfo describing the input audio format
 */
GstAudioInfo *
gst_audio_encoder_get_audio_info (GstAudioEncoder * enc)
{
  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), NULL);

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

/**
 * gst_audio_encoder_set_frame_samples_min:
 * @enc: a #GstAudioEncoder
 * @num: number of samples per frame
 *
 * Sets number of samples (per channel) subclass needs to be handed,
 * at least or will be handed all available if 0.
 *
 * If an exact number of samples is required, gst_audio_encoder_set_frame_samples_max()
 * must be called with the same number.
 *
 * Note: This value will be reset to 0 every time before
 * GstAudioEncoder::set_format() is called.
 */
void
gst_audio_encoder_set_frame_samples_min (GstAudioEncoder * enc, gint num)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

  enc->priv->ctx.frame_samples_min = num;
  GST_LOG_OBJECT (enc, "set to %d", num);
}

/**
 * gst_audio_encoder_get_frame_samples_min:
 * @enc: a #GstAudioEncoder
 *
 * Returns: currently minimum requested samples per frame
 */
gint
gst_audio_encoder_get_frame_samples_min (GstAudioEncoder * enc)
{
  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);

  return enc->priv->ctx.frame_samples_min;
}

/**
 * gst_audio_encoder_set_frame_samples_max:
 * @enc: a #GstAudioEncoder
 * @num: number of samples per frame
 *
 * Sets number of samples (per channel) subclass needs to be handed,
 * at most or will be handed all available if 0.
 *
 * If an exact number of samples is required, gst_audio_encoder_set_frame_samples_min()
 * must be called with the same number.
 *
 * Note: This value will be reset to 0 every time before
 * GstAudioEncoder::set_format() is called.
 */
void
gst_audio_encoder_set_frame_samples_max (GstAudioEncoder * enc, gint num)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

  enc->priv->ctx.frame_samples_max = num;
  GST_LOG_OBJECT (enc, "set to %d", num);
}

/**
 * gst_audio_encoder_get_frame_samples_max:
 * @enc: a #GstAudioEncoder
 *
 * Returns: currently maximum requested samples per frame
 */
gint
gst_audio_encoder_get_frame_samples_max (GstAudioEncoder * enc)
{
  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);

  return enc->priv->ctx.frame_samples_max;
}

/**
 * gst_audio_encoder_set_frame_max:
 * @enc: a #GstAudioEncoder
 * @num: number of frames
 *
 * Sets max number of frames accepted at once (assumed minimally 1).
 * Requires @frame_samples_min and @frame_samples_max to be the equal.
 *
 * Note: This value will be reset to 0 every time before
 * GstAudioEncoder::set_format() is called.
 */
void
gst_audio_encoder_set_frame_max (GstAudioEncoder * enc, gint num)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

  enc->priv->ctx.frame_max = num;
  GST_LOG_OBJECT (enc, "set to %d", num);
}

/**
 * gst_audio_encoder_get_frame_max:
 * @enc: a #GstAudioEncoder
 *
 * Returns: currently configured maximum handled frames
 */
gint
gst_audio_encoder_get_frame_max (GstAudioEncoder * enc)
{
  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);

  return enc->priv->ctx.frame_max;
}

/**
 * gst_audio_encoder_set_lookahead:
 * @enc: a #GstAudioEncoder
 * @num: lookahead
 *
 * Sets encoder lookahead (in units of input rate samples)
 *
 * Note: This value will be reset to 0 every time before
 * GstAudioEncoder::set_format() is called.
 */
void
gst_audio_encoder_set_lookahead (GstAudioEncoder * enc, gint num)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

  enc->priv->ctx.lookahead = num;
  GST_LOG_OBJECT (enc, "set to %d", num);
}

/**
 * gst_audio_encoder_get_lookahead:
 * @enc: a #GstAudioEncoder
 *
 * Returns: currently configured encoder lookahead
 */
gint
gst_audio_encoder_get_lookahead (GstAudioEncoder * enc)
{
  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);

  return enc->priv->ctx.lookahead;
}

/**
 * gst_audio_encoder_set_latency:
 * @enc: a #GstAudioEncoder
 * @min: minimum latency
 * @max: maximum latency
 *
 * Sets encoder latency.
 */
void
gst_audio_encoder_set_latency (GstAudioEncoder * enc,
    GstClockTime min, GstClockTime max)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
  g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min));
  g_return_if_fail (min <= max);

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

  GST_LOG_OBJECT (enc, "set to %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
      GST_TIME_ARGS (min), GST_TIME_ARGS (max));

  /* post latency message on the bus */
  gst_element_post_message (GST_ELEMENT (enc),
      gst_message_new_latency (GST_OBJECT (enc)));
}

/**
 * gst_audio_encoder_get_latency:
 * @enc: a #GstAudioEncoder
 * @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_encoder_get_latency (GstAudioEncoder * enc,
    GstClockTime * min, GstClockTime * max)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

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

/**
 * gst_audio_encoder_set_headers:
 * @enc: a #GstAudioEncoder
 * @headers: (transfer full) (element-type Gst.Buffer): a list of
 *   #GstBuffer containing the codec header
 *
 * Set the codec headers to be sent downstream whenever requested.
 */
void
gst_audio_encoder_set_headers (GstAudioEncoder * enc, GList * headers)
{
  GST_DEBUG_OBJECT (enc, "new headers %p", headers);

  if (enc->priv->ctx.headers) {
    g_list_foreach (enc->priv->ctx.headers, (GFunc) gst_buffer_unref, NULL);
    g_list_free (enc->priv->ctx.headers);
  }
  enc->priv->ctx.headers = headers;
  enc->priv->ctx.new_headers = TRUE;
}

/**
 * gst_audio_encoder_set_allocation_caps:
 * @enc: a #GstAudioEncoder
 * @allocation_caps: (allow-none): a #GstCaps or %NULL
 *
 * Sets a caps in allocation query which are different from the set
 * pad's caps. Use this function before calling
 * gst_audio_encoder_negotiate(). Setting to %NULL the allocation
 * query will use the caps from the pad.
 *
 * Since: 1.10
 */
void
gst_audio_encoder_set_allocation_caps (GstAudioEncoder * enc,
    GstCaps * allocation_caps)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

  gst_caps_replace (&enc->priv->ctx.allocation_caps, allocation_caps);
}

/**
 * gst_audio_encoder_set_mark_granule:
 * @enc: a #GstAudioEncoder
 * @enabled: new state
 *
 * Enable or disable encoder granule handling.
 *
 * MT safe.
 */
void
gst_audio_encoder_set_mark_granule (GstAudioEncoder * enc, gboolean enabled)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

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

  GST_OBJECT_LOCK (enc);
  enc->priv->granule = enabled;
  GST_OBJECT_UNLOCK (enc);
}

/**
 * gst_audio_encoder_get_mark_granule:
 * @enc: a #GstAudioEncoder
 *
 * Queries if the encoder will handle granule marking.
 *
 * Returns: TRUE if granule marking is enabled.
 *
 * MT safe.
 */
gboolean
gst_audio_encoder_get_mark_granule (GstAudioEncoder * enc)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);

  GST_OBJECT_LOCK (enc);
  result = enc->priv->granule;
  GST_OBJECT_UNLOCK (enc);

  return result;
}

/**
 * gst_audio_encoder_set_perfect_timestamp:
 * @enc: a #GstAudioEncoder
 * @enabled: new state
 *
 * Enable or disable encoder perfect output timestamp preference.
 *
 * MT safe.
 */
void
gst_audio_encoder_set_perfect_timestamp (GstAudioEncoder * enc,
    gboolean enabled)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

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

  GST_OBJECT_LOCK (enc);
  enc->priv->perfect_ts = enabled;
  GST_OBJECT_UNLOCK (enc);
}

/**
 * gst_audio_encoder_get_perfect_timestamp:
 * @enc: a #GstAudioEncoder
 *
 * Queries encoder perfect timestamp behaviour.
 *
 * Returns: TRUE if perfect timestamp setting enabled.
 *
 * MT safe.
 */
gboolean
gst_audio_encoder_get_perfect_timestamp (GstAudioEncoder * enc)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);

  GST_OBJECT_LOCK (enc);
  result = enc->priv->perfect_ts;
  GST_OBJECT_UNLOCK (enc);

  return result;
}

/**
 * gst_audio_encoder_set_hard_sync:
 * @enc: a #GstAudioEncoder
 * @enabled: new state
 *
 * Sets encoder hard resync handling.
 *
 * MT safe.
 */
void
gst_audio_encoder_set_hard_resync (GstAudioEncoder * enc, gboolean enabled)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

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

  GST_OBJECT_LOCK (enc);
  enc->priv->hard_resync = enabled;
  GST_OBJECT_UNLOCK (enc);
}

/**
 * gst_audio_encoder_get_hard_sync:
 * @enc: a #GstAudioEncoder
 *
 * Queries encoder's hard resync setting.
 *
 * Returns: TRUE if hard resync is enabled.
 *
 * MT safe.
 */
gboolean
gst_audio_encoder_get_hard_resync (GstAudioEncoder * enc)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);

  GST_OBJECT_LOCK (enc);
  result = enc->priv->hard_resync;
  GST_OBJECT_UNLOCK (enc);

  return result;
}

/**
 * gst_audio_encoder_set_tolerance:
 * @enc: a #GstAudioEncoder
 * @tolerance: new tolerance
 *
 * Configures encoder audio jitter tolerance threshold.
 *
 * MT safe.
 */
void
gst_audio_encoder_set_tolerance (GstAudioEncoder * enc, GstClockTime tolerance)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

  GST_OBJECT_LOCK (enc);
  enc->priv->tolerance = tolerance;
  GST_OBJECT_UNLOCK (enc);

  GST_LOG_OBJECT (enc, "set to %" GST_TIME_FORMAT, GST_TIME_ARGS (tolerance));
}

/**
 * gst_audio_encoder_get_tolerance:
 * @enc: a #GstAudioEncoder
 *
 * Queries current audio jitter tolerance threshold.
 *
 * Returns: encoder audio jitter tolerance threshold.
 *
 * MT safe.
 */
GstClockTime
gst_audio_encoder_get_tolerance (GstAudioEncoder * enc)
{
  GstClockTime result;

  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);

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

  return result;
}

/**
 * gst_audio_encoder_set_hard_min:
 * @enc: a #GstAudioEncoder
 * @enabled: new state
 *
 * Configures encoder hard minimum handling.  If enabled, subclass
 * will never be handed less samples than it configured, which otherwise
 * might occur near end-of-data handling.  Instead, the leftover samples
 * will simply be discarded.
 *
 * MT safe.
 */
void
gst_audio_encoder_set_hard_min (GstAudioEncoder * enc, gboolean enabled)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));

  GST_OBJECT_LOCK (enc);
  enc->priv->hard_min = enabled;
  GST_OBJECT_UNLOCK (enc);
}

/**
 * gst_audio_encoder_get_hard_min:
 * @enc: a #GstAudioEncoder
 *
 * Queries encoder hard minimum handling.
 *
 * Returns: TRUE if hard minimum handling is enabled.
 *
 * MT safe.
 */
gboolean
gst_audio_encoder_get_hard_min (GstAudioEncoder * enc)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);

  GST_OBJECT_LOCK (enc);
  result = enc->priv->hard_min;
  GST_OBJECT_UNLOCK (enc);

  return result;
}

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

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

/**
 * gst_audio_encoder_get_drainable:
 * @enc: a #GstAudioEncoder
 *
 * Queries encoder drain handling.
 *
 * Returns: TRUE if drainable handling is enabled.
 *
 * MT safe.
 */
gboolean
gst_audio_encoder_get_drainable (GstAudioEncoder * enc)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);

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

  return result;
}

/**
 * gst_audio_encoder_merge_tags:
 * @enc: a #GstAudioEncoder
 * @tags: (allow-none): a #GstTagList to merge, or NULL to unset
 *     previously-set tags
 * @mode: the #GstTagMergeMode to use, usually #GST_TAG_MERGE_REPLACE
 *
 * Sets the audio encoder tags and how they should be merged with any
 * upstream stream tags. This will override any tags previously-set
 * with gst_audio_encoder_merge_tags().
 *
 * 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.
 *
 * MT safe.
 */
void
gst_audio_encoder_merge_tags (GstAudioEncoder * enc,
    const GstTagList * tags, GstTagMergeMode mode)
{
  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
  g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));
  g_return_if_fail (tags == NULL || mode != GST_TAG_MERGE_UNDEFINED);

  GST_AUDIO_ENCODER_STREAM_LOCK (enc);
  if (enc->priv->tags != tags) {
    if (enc->priv->tags) {
      gst_tag_list_unref (enc->priv->tags);
      enc->priv->tags = NULL;
      enc->priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
    }
    if (tags) {
      enc->priv->tags = gst_tag_list_ref ((GstTagList *) tags);
      enc->priv->tags_merge_mode = mode;
    }

    GST_DEBUG_OBJECT (enc, "setting encoder tags to %" GST_PTR_FORMAT, tags);
    enc->priv->tags_changed = TRUE;
  }
  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
}

static gboolean
gst_audio_encoder_negotiate_default (GstAudioEncoder * enc)
{
  GstAudioEncoderClass *klass;
  gboolean res = TRUE;
  GstQuery *query = NULL;
  GstAllocator *allocator;
  GstAllocationParams params;
  GstCaps *caps, *prevcaps;

  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);
  g_return_val_if_fail (GST_IS_CAPS (enc->priv->ctx.caps), FALSE);

  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

  caps = enc->priv->ctx.caps;
  if (enc->priv->ctx.allocation_caps == NULL)
    enc->priv->ctx.allocation_caps = gst_caps_ref (caps);

  GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);

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

    pending_events = &enc->priv->pending_events;

    GST_DEBUG_OBJECT (enc, "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_encoder_push_event (enc, 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 (enc->srcpad);
  if (!prevcaps || !gst_caps_is_equal (prevcaps, caps))
    res = gst_pad_set_caps (enc->srcpad, caps);
  if (prevcaps)
    gst_caps_unref (prevcaps);

  if (!res)
    goto done;
  enc->priv->ctx.output_caps_changed = FALSE;

  query = gst_query_new_allocation (enc->priv->ctx.allocation_caps, TRUE);
  if (!gst_pad_peer_query (enc->srcpad, query)) {
    GST_DEBUG_OBJECT (enc, "didn't get downstream ALLOCATION hints");
  }

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

  GST_DEBUG_OBJECT (enc, "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 (enc->priv->ctx.allocator)
    gst_object_unref (enc->priv->ctx.allocator);
  enc->priv->ctx.allocator = allocator;
  enc->priv->ctx.params = params;

done:
  if (query)
    gst_query_unref (query);

  return res;

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

static gboolean
gst_audio_encoder_negotiate_unlocked (GstAudioEncoder * enc)
{
  GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
  gboolean ret = TRUE;

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

  return ret;
}

/**
 * gst_audio_encoder_negotiate:
 * @enc: a #GstAudioEncoder
 *
 * Negotiate with downstream elements to currently configured #GstCaps.
 * 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_encoder_negotiate (GstAudioEncoder * enc)
{
  GstAudioEncoderClass *klass;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);

  klass = GST_AUDIO_ENCODER_GET_CLASS (enc);

  GST_AUDIO_ENCODER_STREAM_LOCK (enc);
  gst_pad_check_reconfigure (enc->srcpad);
  if (klass->negotiate) {
    ret = klass->negotiate (enc);
    if (!ret)
      gst_pad_mark_reconfigure (enc->srcpad);
  }
  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

  return ret;
}

/**
 * gst_audio_encoder_set_output_format:
 * @enc: a #GstAudioEncoder
 * @caps: (transfer none): #GstCaps
 *
 * Configure output caps on the srcpad of @enc.
 *
 * Returns: %TRUE on success.
 */
gboolean
gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps)
{
  gboolean res = TRUE;
  GstCaps *templ_caps;

  GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);

  GST_AUDIO_ENCODER_STREAM_LOCK (enc);
  if (!gst_caps_is_fixed (caps))
    goto refuse_caps;

  /* Only allow caps that are a subset of the template caps */
  templ_caps = gst_pad_get_pad_template_caps (enc->srcpad);
  if (!gst_caps_is_subset (caps, templ_caps)) {
    gst_caps_unref (templ_caps);
    goto refuse_caps;
  }
  gst_caps_unref (templ_caps);

  gst_caps_replace (&enc->priv->ctx.caps, caps);
  enc->priv->ctx.output_caps_changed = TRUE;

done:
  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

  return res;

  /* ERRORS */
refuse_caps:
  {
    GST_WARNING_OBJECT (enc, "refused caps %" GST_PTR_FORMAT, caps);
    res = FALSE;
    goto done;
  }
}

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

  g_return_val_if_fail (size > 0, NULL);

  GST_DEBUG ("alloc src buffer");

  GST_AUDIO_ENCODER_STREAM_LOCK (enc);

  needs_reconfigure = gst_pad_check_reconfigure (enc->srcpad);
  if (G_UNLIKELY (enc->priv->ctx.output_caps_changed || (enc->priv->ctx.caps
              && needs_reconfigure))) {
    if (!gst_audio_encoder_negotiate_unlocked (enc)) {
      GST_INFO_OBJECT (enc, "Failed to negotiate, fallback allocation");
      gst_pad_mark_reconfigure (enc->srcpad);
      goto fallback;
    }
  }

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

  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

  return buffer;

fallback:
  buffer = gst_buffer_new_allocate (NULL, size, NULL);
  GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);

  return buffer;
}

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

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

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