/* GStreamer
 * Copyright (C) 2008 David Schleef <ds@schleef.org>
 * 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>
 * Copyright (C) 2012 Collabora Ltd.
 *	Author : Edward Hervey <edward@collabora.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:gstvideoencoder
 * @title: GstVideoEncoder
 * @short_description: Base class for video encoders
 * @see_also:
 *
 * This base class is for video encoders turning raw video into
 * encoded video data.
 *
 * GstVideoEncoder and subclass should cooperate as follows.
 *
 * ## Configuration
 *
 *   * Initially, GstVideoEncoder calls @start when the encoder element
 *     is activated, which allows subclass to perform any global setup.
 *   * GstVideoEncoder calls @set_format to inform subclass of the format
 *     of input video data that it is about to receive.  Subclass should
 *     setup for encoding and configure base class as appropriate
 *     (e.g. latency). While unlikely, it might be called more than once,
 *     if changing input parameters require reconfiguration.  Baseclass
 *     will ensure that processing of current configuration is finished.
 *   * GstVideoEncoder calls @stop at end of all processing.
 *
 * ## Data processing
 *
 *     * Base class collects input data and metadata into a frame and hands
 *       this to subclass' @handle_frame.
 *
 *     * If codec processing results in encoded data, subclass should call
 *       @gst_video_encoder_finish_frame to have encoded data pushed
 *       downstream.
 *
 *     * If implemented, baseclass calls subclass @pre_push just prior to
 *       pushing to allow subclasses to modify some metadata on the buffer.
 *       If it returns GST_FLOW_OK, the buffer is pushed downstream.
 *
 *     * GstVideoEncoderClass will handle both srcpad and sinkpad events.
 *       Sink events will be passed to subclass if @event callback has been
 *       provided.
 *
 * ## Shutdown phase
 *
 *   * GstVideoEncoder class calls @stop to inform the subclass that data
 *     parsing will be stopped.
 *
 * Subclass is responsible for providing pad template caps for
 * source and sink pads. The pads need to be named "sink" and "src". It should
 * also be able to provide fixed src pad caps in @getcaps by the time it calls
 * @gst_video_encoder_finish_frame.
 *
 * Things that subclass need to take care of:
 *
 *   * Provide pad templates
 *   * Provide source pad caps before pushing the first buffer
 *   * Accept data in @handle_frame and provide encoded results to
 *      @gst_video_encoder_finish_frame.
 *
 */

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

/* TODO
 *
 * * Calculate actual latency based on input/output timestamp/frame_number
 *   and if it exceeds the recorded one, save it and emit a GST_MESSAGE_LATENCY
 */

#include <gst/video/video.h>
#include "gstvideoencoder.h"
#include "gstvideoutils.h"
#include "gstvideoutilsprivate.h"

#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideopool.h>

#include <string.h>

GST_DEBUG_CATEGORY (videoencoder_debug);
#define GST_CAT_DEFAULT videoencoder_debug

#define GST_VIDEO_ENCODER_GET_PRIVATE(obj)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_VIDEO_ENCODER, \
        GstVideoEncoderPrivate))

struct _GstVideoEncoderPrivate
{
  guint64 presentation_frame_number;
  int distance_from_sync;

  /* FIXME : (and introduce a context ?) */
  gboolean drained;

  gint64 min_latency;
  gint64 max_latency;

  GList *current_frame_events;

  GList *headers;
  gboolean new_headers;         /* Whether new headers were just set */

  GList *force_key_unit;        /* List of pending forced keyunits */

  guint32 system_frame_number;

  GList *frames;                /* Protected with OBJECT_LOCK */
  GstVideoCodecState *input_state;
  GstVideoCodecState *output_state;
  gboolean output_state_changed;

  gint64 bytes;
  gint64 time;

  GstAllocator *allocator;
  GstAllocationParams params;

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

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

  gboolean tags_changed;

  GstClockTime min_pts;
  /* adjustment needed on pts, dts, segment start and stop to accomodate
   * min_pts */
  GstClockTime time_adjustment;
};

typedef struct _ForcedKeyUnitEvent ForcedKeyUnitEvent;
struct _ForcedKeyUnitEvent
{
  GstClockTime running_time;
  gboolean pending;             /* TRUE if this was requested already */
  gboolean all_headers;
  guint count;
  guint32 frame_id;
};

static void
forced_key_unit_event_free (ForcedKeyUnitEvent * evt)
{
  g_slice_free (ForcedKeyUnitEvent, evt);
}

static ForcedKeyUnitEvent *
forced_key_unit_event_new (GstClockTime running_time, gboolean all_headers,
    guint count)
{
  ForcedKeyUnitEvent *evt = g_slice_new0 (ForcedKeyUnitEvent);

  evt->running_time = running_time;
  evt->all_headers = all_headers;
  evt->count = count;

  return evt;
}

static GstElementClass *parent_class = NULL;
static void gst_video_encoder_class_init (GstVideoEncoderClass * klass);
static void gst_video_encoder_init (GstVideoEncoder * enc,
    GstVideoEncoderClass * klass);

static void gst_video_encoder_finalize (GObject * object);

static gboolean gst_video_encoder_setcaps (GstVideoEncoder * enc,
    GstCaps * caps);
static GstCaps *gst_video_encoder_sink_getcaps (GstVideoEncoder * encoder,
    GstCaps * filter);
static gboolean gst_video_encoder_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstFlowReturn gst_video_encoder_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static GstStateChangeReturn gst_video_encoder_change_state (GstElement *
    element, GstStateChange transition);
static gboolean gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_video_encoder_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder *
    encoder, GstBuffer * buf, GstClockTime pts, GstClockTime dts,
    GstClockTime duration);

static gboolean gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
    GstEvent * event);
static gboolean gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
    GstEvent * event);
static gboolean gst_video_encoder_decide_allocation_default (GstVideoEncoder *
    encoder, GstQuery * query);
static gboolean gst_video_encoder_propose_allocation_default (GstVideoEncoder *
    encoder, GstQuery * query);
static gboolean gst_video_encoder_negotiate_default (GstVideoEncoder * encoder);
static gboolean gst_video_encoder_negotiate_unlocked (GstVideoEncoder *
    encoder);

static gboolean gst_video_encoder_sink_query_default (GstVideoEncoder * encoder,
    GstQuery * query);
static gboolean gst_video_encoder_src_query_default (GstVideoEncoder * encoder,
    GstQuery * query);

static gboolean gst_video_encoder_transform_meta_default (GstVideoEncoder *
    encoder, GstVideoCodecFrame * frame, GstMeta * meta);

/* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
 * method to get to the padtemplates */
GType
gst_video_encoder_get_type (void)
{
  static volatile gsize type = 0;

  if (g_once_init_enter (&type)) {
    GType _type;
    static const GTypeInfo info = {
      sizeof (GstVideoEncoderClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_video_encoder_class_init,
      NULL,
      NULL,
      sizeof (GstVideoEncoder),
      0,
      (GInstanceInitFunc) gst_video_encoder_init,
    };
    const GInterfaceInfo preset_interface_info = {
      NULL,                     /* interface_init */
      NULL,                     /* interface_finalize */
      NULL                      /* interface_data */
    };

    _type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstVideoEncoder", &info, G_TYPE_FLAG_ABSTRACT);
    g_type_add_interface_static (_type, GST_TYPE_PRESET,
        &preset_interface_info);
    g_once_init_leave (&type, _type);
  }
  return type;
}

static void
gst_video_encoder_class_init (GstVideoEncoderClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  GST_DEBUG_CATEGORY_INIT (videoencoder_debug, "videoencoder", 0,
      "Base Video Encoder");

  parent_class = g_type_class_peek_parent (klass);

  g_type_class_add_private (klass, sizeof (GstVideoEncoderPrivate));

  gobject_class->finalize = gst_video_encoder_finalize;

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_video_encoder_change_state);

  klass->sink_event = gst_video_encoder_sink_event_default;
  klass->src_event = gst_video_encoder_src_event_default;
  klass->propose_allocation = gst_video_encoder_propose_allocation_default;
  klass->decide_allocation = gst_video_encoder_decide_allocation_default;
  klass->negotiate = gst_video_encoder_negotiate_default;
  klass->sink_query = gst_video_encoder_sink_query_default;
  klass->src_query = gst_video_encoder_src_query_default;
  klass->transform_meta = gst_video_encoder_transform_meta_default;
}

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_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard)
{
  GstVideoEncoderPrivate *priv = encoder->priv;
  gboolean ret = TRUE;

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);

  priv->presentation_frame_number = 0;
  priv->distance_from_sync = 0;

  g_list_foreach (priv->force_key_unit, (GFunc) forced_key_unit_event_free,
      NULL);
  g_list_free (priv->force_key_unit);
  priv->force_key_unit = NULL;

  priv->drained = TRUE;

  GST_OBJECT_LOCK (encoder);
  priv->bytes = 0;
  priv->time = 0;
  GST_OBJECT_UNLOCK (encoder);

  priv->time_adjustment = GST_CLOCK_TIME_NONE;

  if (hard) {
    gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
    gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);

    if (priv->input_state)
      gst_video_codec_state_unref (priv->input_state);
    priv->input_state = NULL;
    if (priv->output_state)
      gst_video_codec_state_unref (priv->output_state);
    priv->output_state = NULL;

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

    g_list_foreach (priv->headers, (GFunc) gst_event_unref, NULL);
    g_list_free (priv->headers);
    priv->headers = NULL;
    priv->new_headers = FALSE;

    if (priv->allocator) {
      gst_object_unref (priv->allocator);
      priv->allocator = NULL;
    }

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

  } else {
    GList *l;

    for (l = priv->frames; l; l = l->next) {
      GstVideoCodecFrame *frame = l->data;

      frame->events = _flush_events (encoder->srcpad, frame->events);
    }
    priv->current_frame_events = _flush_events (encoder->srcpad,
        encoder->priv->current_frame_events);
  }

  g_list_foreach (priv->frames, (GFunc) gst_video_codec_frame_unref, NULL);
  g_list_free (priv->frames);
  priv->frames = NULL;

  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return ret;
}

/* Always call reset() in one way or another after this */
static gboolean
gst_video_encoder_flush (GstVideoEncoder * encoder)
{
  GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
  gboolean ret = TRUE;

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  if (klass->flush)
    ret = klass->flush (encoder);

  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
  return ret;
}

static void
gst_video_encoder_init (GstVideoEncoder * encoder, GstVideoEncoderClass * klass)
{
  GstVideoEncoderPrivate *priv;
  GstPadTemplate *pad_template;
  GstPad *pad;

  GST_DEBUG_OBJECT (encoder, "gst_video_encoder_init");

  priv = encoder->priv = GST_VIDEO_ENCODER_GET_PRIVATE (encoder);

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
  g_return_if_fail (pad_template != NULL);

  encoder->sinkpad = pad = gst_pad_new_from_template (pad_template, "sink");

  gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_video_encoder_chain));
  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_encoder_sink_event));
  gst_pad_set_query_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_encoder_sink_query));
  gst_element_add_pad (GST_ELEMENT (encoder), encoder->sinkpad);

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
  g_return_if_fail (pad_template != NULL);

  encoder->srcpad = pad = gst_pad_new_from_template (pad_template, "src");

  gst_pad_set_query_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_encoder_src_query));
  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_encoder_src_event));
  gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad);

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

  g_rec_mutex_init (&encoder->stream_lock);

  priv->headers = NULL;
  priv->new_headers = FALSE;

  priv->min_latency = 0;
  priv->max_latency = 0;
  priv->min_pts = GST_CLOCK_TIME_NONE;
  priv->time_adjustment = GST_CLOCK_TIME_NONE;

  gst_video_encoder_reset (encoder, TRUE);
}

/**
 * gst_video_encoder_set_headers:
 * @encoder: a #GstVideoEncoder
 * @headers: (transfer full) (element-type GstBuffer): a list of #GstBuffer containing the codec header
 *
 * Set the codec headers to be sent downstream whenever requested.
 */
void
gst_video_encoder_set_headers (GstVideoEncoder * video_encoder, GList * headers)
{
  GST_VIDEO_ENCODER_STREAM_LOCK (video_encoder);

  GST_DEBUG_OBJECT (video_encoder, "new headers %p", headers);
  if (video_encoder->priv->headers) {
    g_list_foreach (video_encoder->priv->headers, (GFunc) gst_buffer_unref,
        NULL);
    g_list_free (video_encoder->priv->headers);
  }
  video_encoder->priv->headers = headers;
  video_encoder->priv->new_headers = TRUE;

  GST_VIDEO_ENCODER_STREAM_UNLOCK (video_encoder);
}

static GstVideoCodecState *
_new_output_state (GstCaps * caps, GstVideoCodecState * reference)
{
  GstVideoCodecState *state;

  state = g_slice_new0 (GstVideoCodecState);
  state->ref_count = 1;
  gst_video_info_init (&state->info);

  if (!gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, 0, 0)) {
    g_slice_free (GstVideoCodecState, state);
    return NULL;
  }

  state->caps = caps;

  if (reference) {
    GstVideoInfo *tgt, *ref;

    tgt = &state->info;
    ref = &reference->info;

    /* Copy over extra fields from reference state */
    tgt->interlace_mode = ref->interlace_mode;
    tgt->flags = ref->flags;
    tgt->width = ref->width;
    tgt->height = ref->height;
    tgt->chroma_site = ref->chroma_site;
    tgt->colorimetry = ref->colorimetry;
    tgt->par_n = ref->par_n;
    tgt->par_d = ref->par_d;
    tgt->fps_n = ref->fps_n;
    tgt->fps_d = ref->fps_d;

    GST_VIDEO_INFO_FIELD_ORDER (tgt) = GST_VIDEO_INFO_FIELD_ORDER (ref);

    GST_VIDEO_INFO_MULTIVIEW_MODE (tgt) = GST_VIDEO_INFO_MULTIVIEW_MODE (ref);
    GST_VIDEO_INFO_MULTIVIEW_FLAGS (tgt) = GST_VIDEO_INFO_MULTIVIEW_FLAGS (ref);
  }

  return state;
}

static GstVideoCodecState *
_new_input_state (GstCaps * caps)
{
  GstVideoCodecState *state;

  state = g_slice_new0 (GstVideoCodecState);
  state->ref_count = 1;
  gst_video_info_init (&state->info);
  if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, caps)))
    goto parse_fail;
  state->caps = gst_caps_ref (caps);

  return state;

parse_fail:
  {
    g_slice_free (GstVideoCodecState, state);
    return NULL;
  }
}

static gboolean
gst_video_encoder_setcaps (GstVideoEncoder * encoder, GstCaps * caps)
{
  GstVideoEncoderClass *encoder_class;
  GstVideoCodecState *state;
  gboolean ret;

  encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);

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

  GST_DEBUG_OBJECT (encoder, "setcaps %" GST_PTR_FORMAT, caps);

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);

  if (encoder->priv->input_state) {
    GST_DEBUG_OBJECT (encoder,
        "Checking if caps changed old %" GST_PTR_FORMAT " new %" GST_PTR_FORMAT,
        encoder->priv->input_state->caps, caps);
    if (gst_caps_is_equal (encoder->priv->input_state->caps, caps))
      goto caps_not_changed;
  }

  state = _new_input_state (caps);
  if (G_UNLIKELY (!state))
    goto parse_fail;

  if (encoder->priv->input_state
      && gst_video_info_is_equal (&state->info,
          &encoder->priv->input_state->info)) {
    gst_video_codec_state_unref (state);
    goto caps_not_changed;
  }

  if (encoder_class->reset) {
    GST_FIXME_OBJECT (encoder, "GstVideoEncoder::reset() is deprecated");
    encoder_class->reset (encoder, TRUE);
  }

  /* and subclass should be ready to configure format at any time around */
  ret = encoder_class->set_format (encoder, state);
  if (ret) {
    if (encoder->priv->input_state)
      gst_video_codec_state_unref (encoder->priv->input_state);
    encoder->priv->input_state = state;
  } else {
    gst_video_codec_state_unref (state);
  }

  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  if (!ret)
    GST_WARNING_OBJECT (encoder, "rejected caps %" GST_PTR_FORMAT, caps);

  return ret;

caps_not_changed:
  {
    GST_DEBUG_OBJECT (encoder, "Caps did not change - ignore");
    GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
    return TRUE;
  }

  /* ERRORS */
parse_fail:
  {
    GST_WARNING_OBJECT (encoder, "Failed to parse caps");
    GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
    return FALSE;
  }
}

/**
 * gst_video_encoder_proxy_getcaps:
 * @enc: a #GstVideoEncoder
 * @caps: (allow-none): initial caps
 * @filter: (allow-none): filter caps
 *
 * Returns caps that express @caps (or sink template caps if @caps == NULL)
 * restricted to resolution/format/... combinations supported by downstream
 * elements (e.g. muxers).
 *
 * Returns: (transfer full): a #GstCaps owned by caller
 */
GstCaps *
gst_video_encoder_proxy_getcaps (GstVideoEncoder * encoder, GstCaps * caps,
    GstCaps * filter)
{
  return __gst_video_element_proxy_getcaps (GST_ELEMENT_CAST (encoder),
      GST_VIDEO_ENCODER_SINK_PAD (encoder),
      GST_VIDEO_ENCODER_SRC_PAD (encoder), caps, filter);
}

static GstCaps *
gst_video_encoder_sink_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
{
  GstVideoEncoderClass *klass;
  GstCaps *caps;

  klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);

  if (klass->getcaps)
    caps = klass->getcaps (encoder, filter);
  else
    caps = gst_video_encoder_proxy_getcaps (encoder, NULL, filter);

  GST_LOG_OBJECT (encoder, "Returning caps %" GST_PTR_FORMAT, caps);

  return caps;
}

static gboolean
gst_video_encoder_decide_allocation_default (GstVideoEncoder * encoder,
    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_video_encoder_propose_allocation_default (GstVideoEncoder * encoder,
    GstQuery * query)
{
  GstCaps *caps;
  GstVideoInfo info;
  GstBufferPool *pool;
  guint size;

  gst_query_parse_allocation (query, &caps, NULL);

  if (caps == NULL)
    return FALSE;

  if (!gst_video_info_from_caps (&info, caps))
    return FALSE;

  size = GST_VIDEO_INFO_SIZE (&info);

  if (gst_query_get_n_allocation_pools (query) == 0) {
    GstStructure *structure;
    GstAllocator *allocator = NULL;
    GstAllocationParams params = { 0, 15, 0, 0 };

    if (gst_query_get_n_allocation_params (query) > 0)
      gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
    else
      gst_query_add_allocation_param (query, allocator, &params);

    pool = gst_video_buffer_pool_new ();

    structure = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_set_params (structure, caps, size, 0, 0);
    gst_buffer_pool_config_set_allocator (structure, allocator, &params);

    if (allocator)
      gst_object_unref (allocator);

    if (!gst_buffer_pool_set_config (pool, structure))
      goto config_failed;

    gst_query_add_allocation_pool (query, pool, size, 0, 0);
    gst_object_unref (pool);
    gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
  }

  return TRUE;

  /* ERRORS */
config_failed:
  {
    GST_ERROR_OBJECT (encoder, "failed to set config");
    gst_object_unref (pool);
    return FALSE;
  }
}

static gboolean
gst_video_encoder_sink_query_default (GstVideoEncoder * encoder,
    GstQuery * query)
{
  GstPad *pad = GST_VIDEO_ENCODER_SINK_PAD (encoder);
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_video_encoder_sink_getcaps (encoder, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      GST_DEBUG_OBJECT (encoder, "convert query");

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      GST_OBJECT_LOCK (encoder);
      if (encoder->priv->input_state != NULL)
        res = __gst_video_rawvideo_convert (encoder->priv->input_state,
            src_fmt, src_val, &dest_fmt, &dest_val);
      else
        res = FALSE;
      GST_OBJECT_UNLOCK (encoder);
      if (!res)
        goto error;
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
    case GST_QUERY_ALLOCATION:
    {
      GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);

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

error:
  GST_DEBUG_OBJECT (encoder, "query failed");
  return res;
}

static gboolean
gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstVideoEncoder *encoder;
  GstVideoEncoderClass *encoder_class;
  gboolean ret = FALSE;

  encoder = GST_VIDEO_ENCODER (parent);
  encoder_class = GST_VIDEO_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 void
gst_video_encoder_finalize (GObject * object)
{
  GstVideoEncoder *encoder;

  GST_DEBUG_OBJECT (object, "finalize");

  encoder = GST_VIDEO_ENCODER (object);
  g_rec_mutex_clear (&encoder->stream_lock);

  if (encoder->priv->allocator) {
    gst_object_unref (encoder->priv->allocator);
    encoder->priv->allocator = NULL;
  }

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

static gboolean
gst_video_encoder_push_event (GstVideoEncoder * encoder, GstEvent * event)
{
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      GstSegment segment;

      GST_VIDEO_ENCODER_STREAM_LOCK (encoder);

      gst_event_copy_segment (event, &segment);

      GST_DEBUG_OBJECT (encoder, "segment %" GST_SEGMENT_FORMAT, &segment);

      if (segment.format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (encoder, "received non TIME segment");
        GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
        break;
      }

      if (encoder->priv->time_adjustment != GST_CLOCK_TIME_NONE) {
        segment.start += encoder->priv->time_adjustment;
        if (GST_CLOCK_TIME_IS_VALID (segment.stop)) {
          segment.stop += encoder->priv->time_adjustment;
        }
      }

      encoder->output_segment = segment;
      GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

      gst_event_unref (event);
      event = gst_event_new_segment (&encoder->output_segment);

      break;
    }
    default:
      break;
  }

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

static GstEvent *
gst_video_encoder_create_merged_tags_event (GstVideoEncoder * 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;
  }

  return gst_event_new_tag (merged_tags);
}

static inline void
gst_video_encoder_check_and_push_tags (GstVideoEncoder * encoder)
{
  if (encoder->priv->tags_changed) {
    GstEvent *tags_event;

    tags_event = gst_video_encoder_create_merged_tags_event (encoder);

    if (tags_event != NULL)
      gst_video_encoder_push_event (encoder, tags_event);

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

static gboolean
gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
    GstEvent * event)
{
  GstVideoEncoderClass *encoder_class;
  gboolean ret = FALSE;

  encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_video_encoder_setcaps (encoder, caps);

      gst_event_unref (event);
      event = NULL;
      break;
    }
    case GST_EVENT_EOS:
    {
      GstFlowReturn flow_ret;

      GST_VIDEO_ENCODER_STREAM_LOCK (encoder);

      if (encoder_class->finish) {
        flow_ret = encoder_class->finish (encoder);
      } else {
        flow_ret = GST_FLOW_OK;
      }

      if (encoder->priv->current_frame_events) {
        GList *l;

        for (l = g_list_last (encoder->priv->current_frame_events); l;
            l = g_list_previous (l)) {
          GstEvent *event = GST_EVENT (l->data);

          gst_video_encoder_push_event (encoder, event);
        }
      }
      g_list_free (encoder->priv->current_frame_events);
      encoder->priv->current_frame_events = NULL;

      gst_video_encoder_check_and_push_tags (encoder);

      ret = (flow_ret == GST_FLOW_OK);
      GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment segment;

      GST_VIDEO_ENCODER_STREAM_LOCK (encoder);

      gst_event_copy_segment (event, &segment);

      GST_DEBUG_OBJECT (encoder, "segment %" GST_SEGMENT_FORMAT, &segment);

      if (segment.format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (encoder, "received non TIME newsegment");
        GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
        break;
      }

      encoder->input_segment = segment;
      ret = TRUE;
      GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      if (gst_video_event_is_force_key_unit (event)) {
        GstClockTime running_time;
        gboolean all_headers;
        guint count;

        if (gst_video_event_parse_downstream_force_key_unit (event,
                NULL, NULL, &running_time, &all_headers, &count)) {
          ForcedKeyUnitEvent *fevt;

          GST_OBJECT_LOCK (encoder);
          fevt = forced_key_unit_event_new (running_time, all_headers, count);
          encoder->priv->force_key_unit =
              g_list_append (encoder->priv->force_key_unit, fevt);
          GST_OBJECT_UNLOCK (encoder);

          GST_DEBUG_OBJECT (encoder,
              "force-key-unit event: running-time %" GST_TIME_FORMAT
              ", all_headers %d, count %u",
              GST_TIME_ARGS (running_time), all_headers, count);
        }
        gst_event_unref (event);
        event = NULL;
        ret = TRUE;
      }
      break;
    }
    case GST_EVENT_STREAM_START:
    {
      GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
      /* Flush upstream tags after a STREAM_START */
      GST_DEBUG_OBJECT (encoder, "STREAM_START, clearing upstream tags");
      if (encoder->priv->upstream_tags) {
        gst_tag_list_unref (encoder->priv->upstream_tags);
        encoder->priv->upstream_tags = NULL;
        encoder->priv->tags_changed = TRUE;
      }
      GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
      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_VIDEO_ENCODER_STREAM_LOCK (encoder);
        if (encoder->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 (encoder->priv->upstream_tags)
            gst_tag_list_unref (encoder->priv->upstream_tags);
          encoder->priv->upstream_tags = tags;
          GST_INFO_OBJECT (encoder, "upstream tags: %" GST_PTR_FORMAT, tags);
        }
        gst_event_unref (event);
        event = gst_video_encoder_create_merged_tags_event (encoder);
        GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
        if (!event)
          ret = TRUE;
      }
      break;
    }
    case GST_EVENT_FLUSH_STOP:{
      GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
      gst_video_encoder_flush (encoder);
      gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
      gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
      gst_video_encoder_reset (encoder, FALSE);
      GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
      break;
    }
    default:
      break;
  }

  /* Forward non-serialized events and EOS/FLUSH_STOP immediately.
   * For EOS this is required because no buffer or serialized event
   * will come after EOS and nothing could trigger another
   * _finish_frame() call.   *
   * If the subclass handles sending of EOS manually it can simply
   * not chain up to the parent class' event handler
   *
   * For FLUSH_STOP this is required because it is expected
   * to be forwarded immediately and no buffers are queued anyway.
   */
  if (event) {
    if (!GST_EVENT_IS_SERIALIZED (event)
        || GST_EVENT_TYPE (event) == GST_EVENT_EOS
        || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
      ret = gst_video_encoder_push_event (encoder, event);
    } else {
      GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
      encoder->priv->current_frame_events =
          g_list_prepend (encoder->priv->current_frame_events, event);
      GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
      ret = TRUE;
    }
  }

  return ret;
}

static gboolean
gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstVideoEncoder *enc;
  GstVideoEncoderClass *klass;
  gboolean ret = TRUE;

  enc = GST_VIDEO_ENCODER (parent);
  klass = GST_VIDEO_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);

  return ret;
}

static gboolean
gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
    GstEvent * event)
{
  gboolean ret = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_UPSTREAM:
    {
      if (gst_video_event_is_force_key_unit (event)) {
        GstClockTime running_time;
        gboolean all_headers;
        guint count;

        if (gst_video_event_parse_upstream_force_key_unit (event,
                &running_time, &all_headers, &count)) {
          ForcedKeyUnitEvent *fevt;

          GST_OBJECT_LOCK (encoder);
          fevt = forced_key_unit_event_new (running_time, all_headers, count);
          encoder->priv->force_key_unit =
              g_list_append (encoder->priv->force_key_unit, fevt);
          GST_OBJECT_UNLOCK (encoder);

          GST_DEBUG_OBJECT (encoder,
              "force-key-unit event: running-time %" GST_TIME_FORMAT
              ", all_headers %d, count %u",
              GST_TIME_ARGS (running_time), all_headers, count);
        }
        gst_event_unref (event);
        event = NULL;
        ret = TRUE;
      }
      break;
    }
    default:
      break;
  }

  if (event)
    ret =
        gst_pad_event_default (encoder->srcpad, GST_OBJECT_CAST (encoder),
        event);

  return ret;
}

static gboolean
gst_video_encoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstVideoEncoder *encoder;
  GstVideoEncoderClass *klass;
  gboolean ret = FALSE;

  encoder = GST_VIDEO_ENCODER (parent);
  klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);

  GST_LOG_OBJECT (encoder, "handling event: %" GST_PTR_FORMAT, event);

  if (klass->src_event)
    ret = klass->src_event (encoder, event);

  return ret;
}

static gboolean
gst_video_encoder_src_query_default (GstVideoEncoder * enc, GstQuery * query)
{
  GstPad *pad = GST_VIDEO_ENCODER_SRC_PAD (enc);
  GstVideoEncoderPrivate *priv;
  gboolean res;

  priv = enc->priv;

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

  switch (GST_QUERY_TYPE (query)) {
    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_video_encoded_video_convert (priv->bytes, priv->time, 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);
      break;
    }
    case GST_QUERY_LATENCY:
    {
      gboolean live;
      GstClockTime min_latency, max_latency;

      res = gst_pad_peer_query (enc->sinkpad, query);
      if (res) {
        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);
        min_latency += priv->min_latency;
        if (max_latency == GST_CLOCK_TIME_NONE
            || enc->priv->max_latency == GST_CLOCK_TIME_NONE)
          max_latency = GST_CLOCK_TIME_NONE;
        else
          max_latency += enc->priv->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);
  }
  return res;

error:
  GST_DEBUG_OBJECT (enc, "query failed");
  return res;
}

static gboolean
gst_video_encoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstVideoEncoder *encoder;
  GstVideoEncoderClass *encoder_class;
  gboolean ret = FALSE;

  encoder = GST_VIDEO_ENCODER (parent);
  encoder_class = GST_VIDEO_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 GstVideoCodecFrame *
gst_video_encoder_new_frame (GstVideoEncoder * encoder, GstBuffer * buf,
    GstClockTime pts, GstClockTime dts, GstClockTime duration)
{
  GstVideoEncoderPrivate *priv = encoder->priv;
  GstVideoCodecFrame *frame;

  frame = g_slice_new0 (GstVideoCodecFrame);

  frame->ref_count = 1;

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  frame->system_frame_number = priv->system_frame_number;
  priv->system_frame_number++;

  frame->presentation_frame_number = priv->presentation_frame_number;
  priv->presentation_frame_number++;
  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  frame->events = priv->current_frame_events;
  priv->current_frame_events = NULL;
  frame->input_buffer = buf;
  frame->pts = pts;
  frame->dts = dts;
  frame->duration = duration;
  frame->abidata.ABI.ts = pts;

  return frame;
}


static GstFlowReturn
gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstVideoEncoder *encoder;
  GstVideoEncoderPrivate *priv;
  GstVideoEncoderClass *klass;
  GstVideoCodecFrame *frame;
  GstClockTime pts, duration;
  GstFlowReturn ret = GST_FLOW_OK;
  guint64 start, stop, cstart, cstop;

  encoder = GST_VIDEO_ENCODER (parent);
  priv = encoder->priv;
  klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);

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

  if (!encoder->priv->input_state)
    goto not_negotiated;

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);

  pts = GST_BUFFER_PTS (buf);
  duration = GST_BUFFER_DURATION (buf);

  GST_LOG_OBJECT (encoder,
      "received buffer of size %" G_GSIZE_FORMAT " with PTS %" GST_TIME_FORMAT
      ", DTS %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
      gst_buffer_get_size (buf), GST_TIME_ARGS (pts),
      GST_TIME_ARGS (GST_BUFFER_DTS (buf)), GST_TIME_ARGS (duration));

  start = pts;
  if (GST_CLOCK_TIME_IS_VALID (duration))
    stop = start + duration;
  else
    stop = GST_CLOCK_TIME_NONE;

  /* Drop buffers outside of segment */
  if (!gst_segment_clip (&encoder->input_segment,
          GST_FORMAT_TIME, start, stop, &cstart, &cstop)) {
    GST_DEBUG_OBJECT (encoder, "clipping to segment dropped frame");
    gst_buffer_unref (buf);
    goto done;
  }

  if (GST_CLOCK_TIME_IS_VALID (cstop))
    duration = cstop - cstart;
  else
    duration = GST_CLOCK_TIME_NONE;

  if (priv->min_pts != GST_CLOCK_TIME_NONE
      && priv->time_adjustment == GST_CLOCK_TIME_NONE) {
    if (cstart < priv->min_pts) {
      priv->time_adjustment = priv->min_pts - cstart;
    }
  }

  if (priv->time_adjustment != GST_CLOCK_TIME_NONE) {
    cstart += priv->time_adjustment;
  }

  /* incoming DTS is not really relevant and does not make sense anyway,
   * so pass along _NONE and maybe come up with something better later on */
  frame = gst_video_encoder_new_frame (encoder, buf, cstart,
      GST_CLOCK_TIME_NONE, duration);

  GST_OBJECT_LOCK (encoder);
  if (priv->force_key_unit) {
    ForcedKeyUnitEvent *fevt = NULL;
    GstClockTime running_time;
    GList *l;

    running_time =
        gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
        cstart);

    for (l = priv->force_key_unit; l; l = l->next) {
      ForcedKeyUnitEvent *tmp = l->data;

      /* Skip pending keyunits */
      if (tmp->pending)
        continue;

      /* Simple case, keyunit ASAP */
      if (tmp->running_time == GST_CLOCK_TIME_NONE) {
        fevt = tmp;
        break;
      }

      /* Event for before this frame */
      if (tmp->running_time <= running_time) {
        fevt = tmp;
        break;
      }
    }

    if (fevt) {
      fevt->frame_id = frame->system_frame_number;
      GST_DEBUG_OBJECT (encoder,
          "Forcing a key unit at running time %" GST_TIME_FORMAT,
          GST_TIME_ARGS (running_time));
      GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME (frame);
      if (fevt->all_headers)
        GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME_HEADERS (frame);
      fevt->pending = TRUE;
    }
  }
  GST_OBJECT_UNLOCK (encoder);

  gst_video_codec_frame_ref (frame);
  priv->frames = g_list_append (priv->frames, frame);

  /* new data, more finish needed */
  priv->drained = FALSE;

  GST_LOG_OBJECT (encoder, "passing frame pfn %d to subclass",
      frame->presentation_frame_number);

  ret = klass->handle_frame (encoder, frame);

done:
  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return ret;

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

static GstStateChangeReturn
gst_video_encoder_change_state (GstElement * element, GstStateChange transition)
{
  GstVideoEncoder *encoder;
  GstVideoEncoderClass *encoder_class;
  GstStateChangeReturn ret;

  encoder = GST_VIDEO_ENCODER (element);
  encoder_class = GST_VIDEO_ENCODER_GET_CLASS (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      /* open device/library if needed */
      if (encoder_class->open && !encoder_class->open (encoder))
        goto open_failed;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
      gst_video_encoder_reset (encoder, TRUE);
      GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

      /* Initialize device/library if needed */
      if (encoder_class->start && !encoder_class->start (encoder))
        goto start_failed;
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:{
      gboolean stopped = TRUE;

      if (encoder_class->stop)
        stopped = encoder_class->stop (encoder);

      GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
      gst_video_encoder_reset (encoder, TRUE);
      GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

      if (!stopped)
        goto stop_failed;
      break;
    }
    case GST_STATE_CHANGE_READY_TO_NULL:
      /* close device/library if needed */
      if (encoder_class->close && !encoder_class->close (encoder))
        goto close_failed;
      break;
    default:
      break;
  }

  return ret;

  /* Errors */

open_failed:
  {
    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
        ("Failed to open encoder"));
    return GST_STATE_CHANGE_FAILURE;
  }

start_failed:
  {
    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
        ("Failed to start encoder"));
    return GST_STATE_CHANGE_FAILURE;
  }

stop_failed:
  {
    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
        ("Failed to stop encoder"));
    return GST_STATE_CHANGE_FAILURE;
  }

close_failed:
  {
    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
        ("Failed to close encoder"));
    return GST_STATE_CHANGE_FAILURE;
  }
}

static gboolean
gst_video_encoder_negotiate_default (GstVideoEncoder * encoder)
{
  GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
  GstAllocator *allocator;
  GstAllocationParams params;
  gboolean ret = TRUE;
  GstVideoCodecState *state = encoder->priv->output_state;
  GstVideoInfo *info = &state->info;
  GstQuery *query = NULL;
  GstVideoCodecFrame *frame;
  GstCaps *prevcaps;
  gchar *colorimetry;

  g_return_val_if_fail (state->caps != NULL, FALSE);

  if (encoder->priv->output_state_changed) {
    state->caps = gst_caps_make_writable (state->caps);

    /* Fill caps */
    gst_caps_set_simple (state->caps, "width", G_TYPE_INT, info->width,
        "height", G_TYPE_INT, info->height,
        "pixel-aspect-ratio", GST_TYPE_FRACTION,
        info->par_n, info->par_d, NULL);
    if (info->flags & GST_VIDEO_FLAG_VARIABLE_FPS && info->fps_n != 0) {
      /* variable fps with a max-framerate */
      gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION, 0, 1,
          "max-framerate", GST_TYPE_FRACTION, info->fps_n, info->fps_d, NULL);
    } else {
      /* no variable fps or no max-framerate */
      gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION,
          info->fps_n, info->fps_d, NULL);
    }
    if (state->codec_data)
      gst_caps_set_simple (state->caps, "codec_data", GST_TYPE_BUFFER,
          state->codec_data, NULL);

    gst_caps_set_simple (state->caps, "interlace-mode", G_TYPE_STRING,
        gst_video_interlace_mode_to_string (info->interlace_mode), NULL);
    if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED &&
        GST_VIDEO_INFO_FIELD_ORDER (info) != GST_VIDEO_FIELD_ORDER_UNKNOWN)
      gst_caps_set_simple (state->caps, "field-order", G_TYPE_STRING,
          gst_video_field_order_to_string (GST_VIDEO_INFO_FIELD_ORDER (info)),
          NULL);

    colorimetry = gst_video_colorimetry_to_string (&info->colorimetry);
    if (colorimetry)
      gst_caps_set_simple (state->caps, "colorimetry", G_TYPE_STRING,
          colorimetry, NULL);
    g_free (colorimetry);

    if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN)
      gst_caps_set_simple (state->caps, "chroma-site", G_TYPE_STRING,
          gst_video_chroma_to_string (info->chroma_site), NULL);

    if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != GST_VIDEO_MULTIVIEW_MODE_NONE) {
      const gchar *caps_mview_mode =
          gst_video_multiview_mode_to_caps_string (GST_VIDEO_INFO_MULTIVIEW_MODE
          (info));

      gst_caps_set_simple (state->caps, "multiview-mode", G_TYPE_STRING,
          caps_mview_mode, "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET,
          GST_VIDEO_INFO_MULTIVIEW_FLAGS (info), GST_FLAG_SET_MASK_EXACT, NULL);
    }
    encoder->priv->output_state_changed = FALSE;
  }

  if (state->allocation_caps == NULL)
    state->allocation_caps = gst_caps_ref (state->caps);

  /* Push all pending pre-caps events of the oldest frame before
   * setting caps */
  frame = encoder->priv->frames ? encoder->priv->frames->data : NULL;
  if (frame || encoder->priv->current_frame_events) {
    GList **events, *l;

    if (frame) {
      events = &frame->events;
    } else {
      events = &encoder->priv->current_frame_events;
    }

    for (l = g_list_last (*events); l;) {
      GstEvent *event = GST_EVENT (l->data);
      GList *tmp;

      if (GST_EVENT_TYPE (event) < GST_EVENT_CAPS) {
        gst_video_encoder_push_event (encoder, event);
        tmp = l;
        l = l->prev;
        *events = g_list_delete_link (*events, tmp);
      } else {
        l = l->prev;
      }
    }
  }

  prevcaps = gst_pad_get_current_caps (encoder->srcpad);
  if (!prevcaps || !gst_caps_is_equal (prevcaps, state->caps))
    ret = gst_pad_set_caps (encoder->srcpad, state->caps);
  else
    ret = TRUE;
  if (prevcaps)
    gst_caps_unref (prevcaps);

  if (!ret)
    goto done;

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

  g_assert (klass->decide_allocation != NULL);
  ret = klass->decide_allocation (encoder, query);

  GST_DEBUG_OBJECT (encoder, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, ret,
      query);

  if (!ret)
    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 (encoder->priv->allocator)
    gst_object_unref (encoder->priv->allocator);
  encoder->priv->allocator = allocator;
  encoder->priv->params = params;

done:
  if (query)
    gst_query_unref (query);

  return ret;

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

static gboolean
gst_video_encoder_negotiate_unlocked (GstVideoEncoder * encoder)
{
  GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
  gboolean ret = TRUE;

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

  return ret;
}

/**
 * gst_video_encoder_negotiate:
 * @encoder: a #GstVideoEncoder
 *
 * Negotiate with downstream elements to currently configured #GstVideoCodecState.
 * 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_video_encoder_negotiate (GstVideoEncoder * encoder)
{
  GstVideoEncoderClass *klass;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_VIDEO_ENCODER (encoder), FALSE);
  g_return_val_if_fail (encoder->priv->output_state, FALSE);

  klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  gst_pad_check_reconfigure (encoder->srcpad);
  if (klass->negotiate) {
    ret = klass->negotiate (encoder);
    if (!ret)
      gst_pad_mark_reconfigure (encoder->srcpad);
  }
  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return ret;
}

/**
 * gst_video_encoder_allocate_output_buffer:
 * @encoder: a #GstVideoEncoder
 * @size: size of the buffer
 *
 * Helper function that allocates a buffer to hold an encoded video frame
 * for @encoder's current #GstVideoCodecState.
 *
 * Returns: (transfer full): allocated buffer
 */
GstBuffer *
gst_video_encoder_allocate_output_buffer (GstVideoEncoder * encoder, gsize size)
{
  GstBuffer *buffer;
  gboolean needs_reconfigure = FALSE;

  g_return_val_if_fail (size > 0, NULL);

  GST_DEBUG ("alloc src buffer");

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
  if (G_UNLIKELY (encoder->priv->output_state_changed
          || (encoder->priv->output_state && needs_reconfigure))) {
    if (!gst_video_encoder_negotiate_unlocked (encoder)) {
      GST_DEBUG_OBJECT (encoder, "Failed to negotiate, fallback allocation");
      gst_pad_mark_reconfigure (encoder->srcpad);
      goto fallback;
    }
  }

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

  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return buffer;

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

  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return buffer;
}

/**
 * gst_video_encoder_allocate_output_frame:
 * @encoder: a #GstVideoEncoder
 * @frame: a #GstVideoCodecFrame
 * @size: size of the buffer
 *
 * Helper function that allocates a buffer to hold an encoded video frame for @encoder's
 * current #GstVideoCodecState.  Subclass should already have configured video
 * state and set src pad caps.
 *
 * The buffer allocated here is owned by the frame and you should only
 * keep references to the frame, not the buffer.
 *
 * Returns: %GST_FLOW_OK if an output buffer could be allocated
 */
GstFlowReturn
gst_video_encoder_allocate_output_frame (GstVideoEncoder *
    encoder, GstVideoCodecFrame * frame, gsize size)
{
  gboolean needs_reconfigure = FALSE;

  g_return_val_if_fail (frame->output_buffer == NULL, GST_FLOW_ERROR);

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
  if (G_UNLIKELY (encoder->priv->output_state_changed
          || (encoder->priv->output_state && needs_reconfigure))) {
    if (!gst_video_encoder_negotiate_unlocked (encoder)) {
      GST_DEBUG_OBJECT (encoder, "Failed to negotiate, fallback allocation");
      gst_pad_mark_reconfigure (encoder->srcpad);
    }
  }

  GST_LOG_OBJECT (encoder, "alloc buffer size %" G_GSIZE_FORMAT, size);

  frame->output_buffer =
      gst_buffer_new_allocate (encoder->priv->allocator, size,
      &encoder->priv->params);

  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return frame->output_buffer ? GST_FLOW_OK : GST_FLOW_ERROR;
}

static void
gst_video_encoder_release_frame (GstVideoEncoder * enc,
    GstVideoCodecFrame * frame)
{
  GList *link;

  /* unref once from the list */
  link = g_list_find (enc->priv->frames, frame);
  if (link) {
    gst_video_codec_frame_unref (frame);
    enc->priv->frames = g_list_delete_link (enc->priv->frames, link);
  }
  /* unref because this function takes ownership */
  gst_video_codec_frame_unref (frame);
}

static gboolean
gst_video_encoder_transform_meta_default (GstVideoEncoder *
    encoder, GstVideoCodecFrame * frame, GstMeta * meta)
{
  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_VIDEO_STR))))
    return TRUE;

  return FALSE;
}

typedef struct
{
  GstVideoEncoder *encoder;
  GstVideoCodecFrame *frame;
} CopyMetaData;

static gboolean
foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
{
  CopyMetaData *data = user_data;
  GstVideoEncoder *encoder = data->encoder;
  GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
  GstVideoCodecFrame *frame = data->frame;
  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, frame, *meta);
    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 && info->transform_func) {
    GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
    GST_DEBUG_OBJECT (encoder, "copy metadata %s", g_type_name (info->api));
    /* simply copy then */
    info->transform_func (frame->output_buffer, *meta, inbuf,
        _gst_meta_transform_copy, &copy_data);
  }
  return TRUE;
}

/**
 * gst_video_encoder_finish_frame:
 * @encoder: a #GstVideoEncoder
 * @frame: (transfer full): an encoded #GstVideoCodecFrame
 *
 * @frame must have a valid encoded data buffer, whose metadata fields
 * are then appropriately set according to frame data or no buffer at
 * all if the frame should be dropped.
 * It is subsequently pushed downstream or provided to @pre_push.
 * In any case, the frame is considered finished and released.
 *
 * After calling this function the output buffer of the frame is to be
 * considered read-only. This function will also change the metadata
 * of the buffer.
 *
 * Returns: a #GstFlowReturn resulting from sending data downstream
 */
GstFlowReturn
gst_video_encoder_finish_frame (GstVideoEncoder * encoder,
    GstVideoCodecFrame * frame)
{
  GstVideoEncoderPrivate *priv = encoder->priv;
  GstFlowReturn ret = GST_FLOW_OK;
  GstVideoEncoderClass *encoder_class;
  GList *l;
  gboolean send_headers = FALSE;
  gboolean discont = (frame->presentation_frame_number == 0);
  GstBuffer *buffer;
  gboolean needs_reconfigure = FALSE;

  encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);

  GST_LOG_OBJECT (encoder,
      "finish frame fpn %d", frame->presentation_frame_number);

  GST_LOG_OBJECT (encoder, "frame PTS %" GST_TIME_FORMAT
      ", DTS %" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts),
      GST_TIME_ARGS (frame->dts));

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);

  needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
  if (G_UNLIKELY (priv->output_state_changed || (priv->output_state
              && needs_reconfigure))) {
    if (!gst_video_encoder_negotiate_unlocked (encoder)) {
      gst_pad_mark_reconfigure (encoder->srcpad);
      if (GST_PAD_IS_FLUSHING (encoder->srcpad))
        ret = GST_FLOW_FLUSHING;
      else
        ret = GST_FLOW_NOT_NEGOTIATED;
      goto done;
    }
  }

  if (G_UNLIKELY (priv->output_state == NULL))
    goto no_output_state;

  /* Push all pending events that arrived before this frame */
  for (l = priv->frames; l; l = l->next) {
    GstVideoCodecFrame *tmp = l->data;

    if (tmp->events) {
      GList *k;

      for (k = g_list_last (tmp->events); k; k = k->prev)
        gst_video_encoder_push_event (encoder, k->data);
      g_list_free (tmp->events);
      tmp->events = NULL;
    }

    if (tmp == frame)
      break;
  }

  gst_video_encoder_check_and_push_tags (encoder);

  /* no buffer data means this frame is skipped/dropped */
  if (!frame->output_buffer) {
    GST_DEBUG_OBJECT (encoder, "skipping frame %" GST_TIME_FORMAT,
        GST_TIME_ARGS (frame->pts));
    goto done;
  }

  if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit) {
    GstClockTime stream_time, running_time;
    GstEvent *ev;
    ForcedKeyUnitEvent *fevt = NULL;
    GList *l;

    running_time =
        gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
        frame->pts);

    GST_OBJECT_LOCK (encoder);
    for (l = priv->force_key_unit; l; l = l->next) {
      ForcedKeyUnitEvent *tmp = l->data;

      /* Skip non-pending keyunits */
      if (!tmp->pending)
        continue;

      /* Exact match using the frame id */
      if (frame->system_frame_number == tmp->frame_id) {
        fevt = tmp;
        break;
      }

      /* Simple case, keyunit ASAP */
      if (tmp->running_time == GST_CLOCK_TIME_NONE) {
        fevt = tmp;
        break;
      }

      /* Event for before this frame */
      if (tmp->running_time <= running_time) {
        fevt = tmp;
        break;
      }
    }

    if (fevt) {
      priv->force_key_unit = g_list_remove (priv->force_key_unit, fevt);
    }
    GST_OBJECT_UNLOCK (encoder);

    if (fevt) {
      stream_time =
          gst_segment_to_stream_time (&encoder->output_segment, GST_FORMAT_TIME,
          frame->pts);

      ev = gst_video_event_new_downstream_force_key_unit
          (frame->pts, stream_time, running_time,
          fevt->all_headers, fevt->count);

      gst_video_encoder_push_event (encoder, ev);

      if (fevt->all_headers)
        send_headers = TRUE;

      GST_DEBUG_OBJECT (encoder,
          "Forced key unit: running-time %" GST_TIME_FORMAT
          ", all_headers %d, count %u",
          GST_TIME_ARGS (running_time), fevt->all_headers, fevt->count);
      forced_key_unit_event_free (fevt);
    }
  }

  if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
    priv->distance_from_sync = 0;
    GST_BUFFER_FLAG_UNSET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
    /* For keyframes, DTS = PTS, if encoder doesn't decide otherwise */
    if (!GST_CLOCK_TIME_IS_VALID (frame->dts)) {
      frame->dts = frame->pts;
    }
  } else {
    GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
  }

  /* DTS is expected monotone ascending,
   * so a good guess is the lowest unsent PTS (all being OK) */
  {
    GstClockTime min_ts = GST_CLOCK_TIME_NONE;
    GstVideoCodecFrame *oframe = NULL;
    gboolean seen_none = FALSE;

    /* some maintenance regardless */
    for (l = priv->frames; l; l = l->next) {
      GstVideoCodecFrame *tmp = l->data;

      if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts)) {
        seen_none = TRUE;
        continue;
      }

      if (!GST_CLOCK_TIME_IS_VALID (min_ts) || tmp->abidata.ABI.ts < min_ts) {
        min_ts = tmp->abidata.ABI.ts;
        oframe = tmp;
      }
    }
    /* save a ts if needed */
    if (oframe && oframe != frame) {
      oframe->abidata.ABI.ts = frame->abidata.ABI.ts;
    }

    /* and set if needed */
    if (!GST_CLOCK_TIME_IS_VALID (frame->dts) && !seen_none) {
      frame->dts = min_ts;
      GST_DEBUG_OBJECT (encoder,
          "no valid DTS, using oldest PTS %" GST_TIME_FORMAT,
          GST_TIME_ARGS (frame->pts));
    }
  }

  frame->distance_from_sync = priv->distance_from_sync;
  priv->distance_from_sync++;

  GST_BUFFER_PTS (frame->output_buffer) = frame->pts;
  GST_BUFFER_DTS (frame->output_buffer) = frame->dts;
  GST_BUFFER_DURATION (frame->output_buffer) = frame->duration;

  GST_OBJECT_LOCK (encoder);
  /* update rate estimate */
  priv->bytes += gst_buffer_get_size (frame->output_buffer);
  if (GST_CLOCK_TIME_IS_VALID (frame->duration)) {
    priv->time += frame->duration;
  } else {
    /* better none than nothing valid */
    priv->time = GST_CLOCK_TIME_NONE;
  }
  GST_OBJECT_UNLOCK (encoder);

  if (G_UNLIKELY (send_headers || priv->new_headers)) {
    GList *tmp, *copy = NULL;

    GST_DEBUG_OBJECT (encoder, "Sending headers");

    /* First make all buffers metadata-writable */
    for (tmp = priv->headers; tmp; tmp = tmp->next) {
      GstBuffer *tmpbuf = GST_BUFFER (tmp->data);

      copy = g_list_append (copy, gst_buffer_make_writable (tmpbuf));
    }
    g_list_free (priv->headers);
    priv->headers = copy;

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

      GST_OBJECT_LOCK (encoder);
      priv->bytes += gst_buffer_get_size (tmpbuf);
      GST_OBJECT_UNLOCK (encoder);
      if (G_UNLIKELY (discont)) {
        GST_LOG_OBJECT (encoder, "marking discont");
        GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
        discont = FALSE;
      }

      gst_pad_push (encoder->srcpad, gst_buffer_ref (tmpbuf));
    }
    priv->new_headers = FALSE;
  }

  if (G_UNLIKELY (discont)) {
    GST_LOG_OBJECT (encoder, "marking discont");
    GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DISCONT);
  }

  if (encoder_class->pre_push)
    ret = encoder_class->pre_push (encoder, frame);

  if (encoder_class->transform_meta) {
    if (G_LIKELY (frame->input_buffer)) {
      CopyMetaData data;

      data.encoder = encoder;
      data.frame = frame;
      gst_buffer_foreach_meta (frame->input_buffer, foreach_metadata, &data);
    } else {
      GST_WARNING_OBJECT (encoder,
          "Can't copy metadata because input frame disappeared");
    }
  }

  /* Get an additional ref to the buffer, which is going to be pushed
   * downstream, the original ref is owned by the frame */
  if (ret == GST_FLOW_OK)
    buffer = gst_buffer_ref (frame->output_buffer);

  /* Release frame so the buffer is writable when we push it downstream
   * if possible, i.e. if the subclass does not hold additional references
   * to the frame
   */
  gst_video_encoder_release_frame (encoder, frame);
  frame = NULL;

  if (ret == GST_FLOW_OK)
    ret = gst_pad_push (encoder->srcpad, buffer);

done:
  /* handed out */
  if (frame)
    gst_video_encoder_release_frame (encoder, frame);

  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return ret;

  /* ERRORS */
no_output_state:
  {
    gst_video_encoder_release_frame (encoder, frame);
    GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
    GST_ERROR_OBJECT (encoder, "Output state was not configured");
    return GST_FLOW_ERROR;
  }
}

/**
 * gst_video_encoder_get_output_state:
 * @encoder: a #GstVideoEncoder
 *
 * Get the current #GstVideoCodecState
 *
 * Returns: (transfer full): #GstVideoCodecState describing format of video data.
 */
GstVideoCodecState *
gst_video_encoder_get_output_state (GstVideoEncoder * encoder)
{
  GstVideoCodecState *state;

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  state = gst_video_codec_state_ref (encoder->priv->output_state);
  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return state;
}

/**
 * gst_video_encoder_set_output_state:
 * @encoder: a #GstVideoEncoder
 * @caps: (transfer full): the #GstCaps to use for the output
 * @reference: (allow-none) (transfer none): An optional reference @GstVideoCodecState
 *
 * Creates a new #GstVideoCodecState with the specified caps as the output state
 * for the encoder.
 * Any previously set output state on @encoder will be replaced by the newly
 * created one.
 *
 * The specified @caps should not contain any resolution, pixel-aspect-ratio,
 * framerate, codec-data, .... Those should be specified instead in the returned
 * #GstVideoCodecState.
 *
 * If the subclass wishes to copy over existing fields (like pixel aspect ratio,
 * or framerate) from an existing #GstVideoCodecState, it can be provided as a
 * @reference.
 *
 * If the subclass wishes to override some fields from the output state (like
 * pixel-aspect-ratio or framerate) it can do so on the returned #GstVideoCodecState.
 *
 * The new output state will only take effect (set on pads and buffers) starting
 * from the next call to #gst_video_encoder_finish_frame().
 *
 * Returns: (transfer full): the newly configured output state.
 */
GstVideoCodecState *
gst_video_encoder_set_output_state (GstVideoEncoder * encoder, GstCaps * caps,
    GstVideoCodecState * reference)
{
  GstVideoEncoderPrivate *priv = encoder->priv;
  GstVideoCodecState *state;

  g_return_val_if_fail (caps != NULL, NULL);

  state = _new_output_state (caps, reference);
  if (!state)
    return NULL;

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  if (priv->output_state)
    gst_video_codec_state_unref (priv->output_state);
  priv->output_state = gst_video_codec_state_ref (state);

  priv->output_state_changed = TRUE;
  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return state;
}

/**
 * gst_video_encoder_set_latency:
 * @encoder: a #GstVideoEncoder
 * @min_latency: minimum latency
 * @max_latency: maximum latency
 *
 * Informs baseclass of encoding latency.
 */
void
gst_video_encoder_set_latency (GstVideoEncoder * encoder,
    GstClockTime min_latency, GstClockTime max_latency)
{
  g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min_latency));
  g_return_if_fail (max_latency >= min_latency);

  GST_OBJECT_LOCK (encoder);
  encoder->priv->min_latency = min_latency;
  encoder->priv->max_latency = max_latency;
  GST_OBJECT_UNLOCK (encoder);

  gst_element_post_message (GST_ELEMENT_CAST (encoder),
      gst_message_new_latency (GST_OBJECT_CAST (encoder)));
}

/**
 * gst_video_encoder_get_latency:
 * @encoder: a #GstVideoEncoder
 * @min_latency: (out) (allow-none): address of variable in which to store the
 *     configured minimum latency, or %NULL
 * @max_latency: (out) (allow-none): address of variable in which to store the
 *     configured maximum latency, or %NULL
 *
 * Query the configured encoding latency. Results will be returned via
 * @min_latency and @max_latency.
 */
void
gst_video_encoder_get_latency (GstVideoEncoder * encoder,
    GstClockTime * min_latency, GstClockTime * max_latency)
{
  GST_OBJECT_LOCK (encoder);
  if (min_latency)
    *min_latency = encoder->priv->min_latency;
  if (max_latency)
    *max_latency = encoder->priv->max_latency;
  GST_OBJECT_UNLOCK (encoder);
}

/**
 * gst_video_encoder_get_oldest_frame:
 * @encoder: a #GstVideoEncoder
 *
 * Get the oldest unfinished pending #GstVideoCodecFrame
 *
 * Returns: (transfer full): oldest unfinished pending #GstVideoCodecFrame
 */
GstVideoCodecFrame *
gst_video_encoder_get_oldest_frame (GstVideoEncoder * encoder)
{
  GstVideoCodecFrame *frame = NULL;

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  if (encoder->priv->frames)
    frame = gst_video_codec_frame_ref (encoder->priv->frames->data);
  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return (GstVideoCodecFrame *) frame;
}

/**
 * gst_video_encoder_get_frame:
 * @encoder: a #GstVideoEnccoder
 * @frame_number: system_frame_number of a frame
 *
 * Get a pending unfinished #GstVideoCodecFrame
 *
 * Returns: (transfer full): pending unfinished #GstVideoCodecFrame identified by @frame_number.
 */
GstVideoCodecFrame *
gst_video_encoder_get_frame (GstVideoEncoder * encoder, int frame_number)
{
  GList *g;
  GstVideoCodecFrame *frame = NULL;

  GST_DEBUG_OBJECT (encoder, "frame_number : %d", frame_number);

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  for (g = encoder->priv->frames; g; g = g->next) {
    GstVideoCodecFrame *tmp = g->data;

    if (tmp->system_frame_number == frame_number) {
      frame = gst_video_codec_frame_ref (tmp);
      break;
    }
  }
  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return frame;
}

/**
 * gst_video_encoder_get_frames:
 * @encoder: a #GstVideoEncoder
 *
 * Get all pending unfinished #GstVideoCodecFrame
 *
 * Returns: (transfer full) (element-type GstVideoCodecFrame): pending unfinished #GstVideoCodecFrame.
 */
GList *
gst_video_encoder_get_frames (GstVideoEncoder * encoder)
{
  GList *frames;

  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
  frames = g_list_copy (encoder->priv->frames);
  g_list_foreach (frames, (GFunc) gst_video_codec_frame_ref, NULL);
  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);

  return frames;
}

/**
 * gst_video_encoder_merge_tags:
 * @encoder: a #GstVideoEncoder
 * @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 video encoder tags and how they should be merged with any
 * upstream stream tags. This will override any tags previously-set
 * with gst_video_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_video_encoder_merge_tags (GstVideoEncoder * encoder,
    const GstTagList * tags, GstTagMergeMode mode)
{
  g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
  g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));
  g_return_if_fail (tags == NULL || mode != GST_TAG_MERGE_UNDEFINED);

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

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

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

  if (allocator)
    *allocator = encoder->priv->allocator ?
        gst_object_ref (encoder->priv->allocator) : NULL;

  if (params)
    *params = encoder->priv->params;
}

/**
 * gst_video_encoder_set_min_pts:
 * @encoder: a #GstVideoEncoder
 * @min_pts: minimal PTS that will be passed to handle_frame
 *
 * Request minimal value for PTS passed to handle_frame.
 *
 * For streams with reordered frames this can be used to ensure that there
 * is enough time to accomodate first DTS, which may be less than first PTS
 *
 * Since 1.6
 */
void
gst_video_encoder_set_min_pts (GstVideoEncoder * encoder, GstClockTime min_pts)
{
  g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
  encoder->priv->min_pts = min_pts;
  encoder->priv->time_adjustment = GST_CLOCK_TIME_NONE;
}
