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

        gst_pad_push (enc->srcpad, tmpbuf);
      }
      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;
}
