/* 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:gstvideodecoder
 * @title: GstVideoDecoder
 * @short_description: Base class for video decoders
 * @see_also:
 *
 * This base class is for video decoders turning encoded data into raw video
 * frames.
 *
 * The GstVideoDecoder base class and derived subclasses should cooperate as
 * follows:
 *
 * ## Configuration
 *
 *   * Initially, GstVideoDecoder calls @start when the decoder element
 *     is activated, which allows the subclass to perform any global setup.
 *
 *   * GstVideoDecoder calls @set_format to inform the subclass of caps
 *     describing input video data that it is about to receive, including
 *     possibly configuration data.
 *     While unlikely, it might be called more than once, if changing input
 *     parameters require reconfiguration.
 *
 *   * Incoming data buffers are processed as needed, described in Data
 *     Processing below.
 *
 *   * GstVideoDecoder calls @stop at end of all processing.
 *
 * ## Data processing
 *
 *     * The base class gathers input data, and optionally allows subclass
 *       to parse this into subsequently manageable chunks, typically
 *       corresponding to and referred to as 'frames'.
 *
 *     * Each input frame is provided in turn to the subclass' @handle_frame
 *       callback.
 *       The ownership of the frame is given to the @handle_frame callback.
 *
 *     * If codec processing results in decoded data, the subclass should call
 *       @gst_video_decoder_finish_frame to have decoded data pushed.
 *       downstream. Otherwise, the subclass must call
 *       @gst_video_decoder_drop_frame, to allow the base class to do timestamp
 *       and offset tracking, and possibly to requeue the frame for a later
 *       attempt in the case of reverse playback.
 *
 * ## Shutdown phase
 *
 *   * The GstVideoDecoder class calls @stop to inform the subclass that data
 *     parsing will be stopped.
 *
 * ## Additional Notes
 *
 *   * Seeking/Flushing
 *
 *     * When the pipeline is seeked or otherwise flushed, the subclass is
 *       informed via a call to its @reset callback, with the hard parameter
 *       set to true. This indicates the subclass should drop any internal data
 *       queues and timestamps and prepare for a fresh set of buffers to arrive
 *       for parsing and decoding.
 *
 *   * End Of Stream
 *
 *     * At end-of-stream, the subclass @parse function may be called some final
 *       times with the at_eos parameter set to true, indicating that the element
 *       should not expect any more data to be arriving, and it should parse and
 *       remaining frames and call gst_video_decoder_have_frame() if possible.
 *
 * The 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 provide information about the ouptput caps, when they are known.
 * This may be when the base class calls the subclass' @set_format function,
 * though it might be during decoding, before calling
 * @gst_video_decoder_finish_frame. This is done via
 * @gst_video_decoder_set_output_state
 *
 * The subclass is also responsible for providing (presentation) timestamps
 * (likely based on corresponding input ones).  If that is not applicable
 * or possible, the base class provides limited framerate based interpolation.
 *
 * Similarly, the base class provides some limited (legacy) seeking support
 * if specifically requested by the subclass, as full-fledged support
 * should rather be left to upstream demuxer, parser or alike.  This simple
 * approach caters for seeking and duration reporting using estimated input
 * bitrates. To enable it, a subclass should call
 * @gst_video_decoder_set_estimate_rate to enable handling of incoming
 * byte-streams.
 *
 * The base class provides some support for reverse playback, in particular
 * in case incoming data is not packetized or upstream does not provide
 * fragments on keyframe boundaries.  However, the subclass should then be
 * prepared for the parsing and frame processing stage to occur separately
 * (in normal forward processing, the latter immediately follows the former),
 * The subclass also needs to ensure the parsing stage properly marks
 * keyframes, unless it knows the upstream elements will do so properly for
 * incoming data.
 *
 * The bare minimum that a functional subclass needs to implement is:
 *
 *   * Provide pad templates
 *   * Inform the base class of output caps via
 *      @gst_video_decoder_set_output_state
 *
 *   * Parse input data, if it is not considered packetized from upstream
 *      Data will be provided to @parse which should invoke
 *      @gst_video_decoder_add_to_frame and @gst_video_decoder_have_frame to
 *      separate the data belonging to each video frame.
 *
 *   * Accept data in @handle_frame and provide decoded results to
 *      @gst_video_decoder_finish_frame, or call @gst_video_decoder_drop_frame.
 */

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

/* TODO
 *
 * * Add a flag/boolean for I-frame-only/image decoders so we can do extra
 *   features, like applying QoS on input (as opposed to after the frame is
 *   decoded).
 * * Add a flag/boolean for decoders that require keyframes, so the base
 *   class can automatically discard non-keyframes before one has arrived
 * * Detect reordered frame/timestamps and fix the pts/dts
 * * Support for GstIndex (or shall we not care ?)
 * * 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
 * * Emit latency message when it changes
 *
 */

/* Implementation notes:
 * The Video Decoder base class operates in 2 primary processing modes, depending
 * on whether forward or reverse playback is requested.
 *
 * Forward playback:
 *   * Incoming buffer -> @parse() -> add_to_frame()/have_frame() ->
 *     handle_frame() -> push downstream
 *
 * Reverse playback is more complicated, since it involves gathering incoming
 * data regions as we loop backwards through the upstream data. The processing
 * concept (using incoming buffers as containing one frame each to simplify
 * things) is:
 *
 * Upstream data we want to play:
 *  Buffer encoded order:  1  2  3  4  5  6  7  8  9  EOS
 *  Keyframe flag:            K        K
 *  Groupings:             AAAAAAA  BBBBBBB  CCCCCCC
 *
 * Input:
 *  Buffer reception order:  7  8  9  4  5  6  1  2  3  EOS
 *  Keyframe flag:                       K        K
 *  Discont flag:            D        D        D
 *
 * - Each Discont marks a discont in the decoding order.
 * - The keyframes mark where we can start decoding.
 *
 * Initially, we prepend incoming buffers to the gather queue. Whenever the
 * discont flag is set on an incoming buffer, the gather queue is flushed out
 * before the new buffer is collected.
 *
 * The above data will be accumulated in the gather queue like this:
 *
 *   gather queue:  9  8  7
 *                        D
 *
 * When buffer 4 is received (with a DISCONT), we flush the gather queue like
 * this:
 *
 *   while (gather)
 *     take head of queue and prepend to parse queue (this reverses the
 *     sequence, so parse queue is 7 -> 8 -> 9)
 *
 *   Next, we process the parse queue, which now contains all un-parsed packets
 *   (including any leftover ones from the previous decode section)
 *
 *   for each buffer now in the parse queue:
 *     Call the subclass parse function, prepending each resulting frame to
 *     the parse_gather queue. Buffers which precede the first one that
 *     produces a parsed frame are retained in the parse queue for
 *     re-processing on the next cycle of parsing.
 *
 *   The parse_gather queue now contains frame objects ready for decoding,
 *   in reverse order.
 *   parse_gather: 9 -> 8 -> 7
 *
 *   while (parse_gather)
 *     Take the head of the queue and prepend it to the decode queue
 *     If the frame was a keyframe, process the decode queue
 *   decode is now 7-8-9
 *
 *  Processing the decode queue results in frames with attached output buffers
 *  stored in the 'output_queue' ready for outputting in reverse order.
 *
 * After we flushed the gather queue and parsed it, we add 4 to the (now empty)
 * gather queue. We get the following situation:
 *
 *  gather queue:    4
 *  decode queue:    7  8  9
 *
 * After we received 5 (Keyframe) and 6:
 *
 *  gather queue:    6  5  4
 *  decode queue:    7  8  9
 *
 * When we receive 1 (DISCONT) which triggers a flush of the gather queue:
 *
 *   Copy head of the gather queue (6) to decode queue:
 *
 *    gather queue:    5  4
 *    decode queue:    6  7  8  9
 *
 *   Copy head of the gather queue (5) to decode queue. This is a keyframe so we
 *   can start decoding.
 *
 *    gather queue:    4
 *    decode queue:    5  6  7  8  9
 *
 *   Decode frames in decode queue, store raw decoded data in output queue, we
 *   can take the head of the decode queue and prepend the decoded result in the
 *   output queue:
 *
 *    gather queue:    4
 *    decode queue:
 *    output queue:    9  8  7  6  5
 *
 *   Now output all the frames in the output queue, picking a frame from the
 *   head of the queue.
 *
 *   Copy head of the gather queue (4) to decode queue, we flushed the gather
 *   queue and can now store input buffer in the gather queue:
 *
 *    gather queue:    1
 *    decode queue:    4
 *
 *  When we receive EOS, the queue looks like:
 *
 *    gather queue:    3  2  1
 *    decode queue:    4
 *
 *  Fill decode queue, first keyframe we copy is 2:
 *
 *    gather queue:    1
 *    decode queue:    2  3  4
 *
 *  Decoded output:
 *
 *    gather queue:    1
 *    decode queue:
 *    output queue:    4  3  2
 *
 *  Leftover buffer 1 cannot be decoded and must be discarded.
 */

#include "gstvideodecoder.h"
#include "gstvideoutils.h"
#include "gstvideoutilsprivate.h"

#include <gst/video/video.h>
#include <gst/video/video-event.h>
#include <gst/video/gstvideopool.h>
#include <gst/video/gstvideometa.h>
#include <string.h>

GST_DEBUG_CATEGORY (videodecoder_debug);
#define GST_CAT_DEFAULT videodecoder_debug

#define GST_VIDEO_DECODER_GET_PRIVATE(obj)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_VIDEO_DECODER, \
        GstVideoDecoderPrivate))

struct _GstVideoDecoderPrivate
{
  /* FIXME introduce a context ? */

  GstBufferPool *pool;
  GstAllocator *allocator;
  GstAllocationParams params;

  /* parse tracking */
  /* input data */
  GstAdapter *input_adapter;
  /* assembles current frame */
  GstAdapter *output_adapter;

  /* Whether we attempt to convert newsegment from bytes to
   * time using a bitrate estimation */
  gboolean do_estimate_rate;

  /* Whether input is considered packetized or not */
  gboolean packetized;

  /* Error handling */
  gint max_errors;
  gint error_count;
  gboolean had_output_data;
  gboolean had_input_data;

  gboolean needs_format;
  /* input_segment are output_segment identical */
  gboolean in_out_segment_sync;

  /* ... being tracked here;
   * only available during parsing */
  GstVideoCodecFrame *current_frame;
  /* events that should apply to the current frame */
  GList *current_frame_events;
  /* events that should be pushed before the next frame */
  GList *pending_events;

  /* relative offset of input data */
  guint64 input_offset;
  /* relative offset of frame */
  guint64 frame_offset;
  /* tracking ts and offsets */
  GList *timestamps;

  /* last outgoing ts */
  GstClockTime last_timestamp_out;
  /* incoming pts - dts */
  GstClockTime pts_delta;
  gboolean reordered_output;

  /* reverse playback */
  /* collect input */
  GList *gather;
  /* to-be-parsed */
  GList *parse;
  /* collected parsed frames */
  GList *parse_gather;
  /* frames to be handled == decoded */
  GList *decode;
  /* collected output - of buffer objects, not frames */
  GList *output_queued;


  /* base_picture_number is the picture number of the reference picture */
  guint64 base_picture_number;
  /* combine with base_picture_number, framerate and calcs to yield (presentation) ts */
  GstClockTime base_timestamp;

  /* FIXME : reorder_depth is never set */
  int reorder_depth;
  int distance_from_sync;

  guint32 system_frame_number;
  guint32 decode_frame_number;

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

  /* QoS properties */
  gdouble proportion;           /* OBJECT_LOCK */
  GstClockTime earliest_time;   /* OBJECT_LOCK */
  GstClockTime qos_frame_duration;      /* OBJECT_LOCK */
  gboolean discont;
  /* qos messages: frames dropped/processed */
  guint dropped;
  guint processed;

  /* Outgoing byte size ? */
  gint64 bytes_out;
  gint64 time;

  gint64 min_latency;
  gint64 max_latency;

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

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

  gboolean tags_changed;

  /* flags */
  gboolean use_default_pad_acceptcaps;

#ifndef GST_DISABLE_DEBUG
  /* Diagnostic time for reporting the time
   * from flush to first output */
  GstClockTime last_reset_time;
#endif
};

static GstElementClass *parent_class = NULL;
static void gst_video_decoder_class_init (GstVideoDecoderClass * klass);
static void gst_video_decoder_init (GstVideoDecoder * dec,
    GstVideoDecoderClass * klass);

static void gst_video_decoder_finalize (GObject * object);

static gboolean gst_video_decoder_setcaps (GstVideoDecoder * dec,
    GstCaps * caps);
static gboolean gst_video_decoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_video_decoder_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstFlowReturn gst_video_decoder_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static gboolean gst_video_decoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstStateChangeReturn gst_video_decoder_change_state (GstElement *
    element, GstStateChange transition);
static gboolean gst_video_decoder_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static void gst_video_decoder_reset (GstVideoDecoder * decoder, gboolean full,
    gboolean flush_hard);

static GstFlowReturn gst_video_decoder_decode_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame);

static void gst_video_decoder_push_event_list (GstVideoDecoder * decoder,
    GList * events);
static GstClockTime gst_video_decoder_get_frame_duration (GstVideoDecoder *
    decoder, GstVideoCodecFrame * frame);
static GstVideoCodecFrame *gst_video_decoder_new_frame (GstVideoDecoder *
    decoder);
static GstFlowReturn gst_video_decoder_clip_and_push_buf (GstVideoDecoder *
    decoder, GstBuffer * buf);
static GstFlowReturn gst_video_decoder_flush_parse (GstVideoDecoder * dec,
    gboolean at_eos);

static void gst_video_decoder_clear_queues (GstVideoDecoder * dec);

static gboolean gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
    GstEvent * event);
static gboolean gst_video_decoder_src_event_default (GstVideoDecoder * decoder,
    GstEvent * event);
static gboolean gst_video_decoder_decide_allocation_default (GstVideoDecoder *
    decoder, GstQuery * query);
static gboolean gst_video_decoder_propose_allocation_default (GstVideoDecoder *
    decoder, GstQuery * query);
static gboolean gst_video_decoder_negotiate_default (GstVideoDecoder * decoder);
static GstFlowReturn gst_video_decoder_parse_available (GstVideoDecoder * dec,
    gboolean at_eos, gboolean new_buffer);
static gboolean gst_video_decoder_negotiate_unlocked (GstVideoDecoder *
    decoder);
static gboolean gst_video_decoder_sink_query_default (GstVideoDecoder * decoder,
    GstQuery * query);
static gboolean gst_video_decoder_src_query_default (GstVideoDecoder * decoder,
    GstQuery * query);

static gboolean gst_video_decoder_transform_meta_default (GstVideoDecoder *
    decoder, 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_decoder_get_type (void)
{
  static volatile gsize type = 0;

  if (g_once_init_enter (&type)) {
    GType _type;
    static const GTypeInfo info = {
      sizeof (GstVideoDecoderClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_video_decoder_class_init,
      NULL,
      NULL,
      sizeof (GstVideoDecoder),
      0,
      (GInstanceInitFunc) gst_video_decoder_init,
    };

    _type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstVideoDecoder", &info, G_TYPE_FLAG_ABSTRACT);
    g_once_init_leave (&type, _type);
  }
  return type;
}

static void
gst_video_decoder_class_init (GstVideoDecoderClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  GST_DEBUG_CATEGORY_INIT (videodecoder_debug, "videodecoder", 0,
      "Base Video Decoder");

  parent_class = g_type_class_peek_parent (klass);
  g_type_class_add_private (klass, sizeof (GstVideoDecoderPrivate));

  gobject_class->finalize = gst_video_decoder_finalize;

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_video_decoder_change_state);

  klass->sink_event = gst_video_decoder_sink_event_default;
  klass->src_event = gst_video_decoder_src_event_default;
  klass->decide_allocation = gst_video_decoder_decide_allocation_default;
  klass->propose_allocation = gst_video_decoder_propose_allocation_default;
  klass->negotiate = gst_video_decoder_negotiate_default;
  klass->sink_query = gst_video_decoder_sink_query_default;
  klass->src_query = gst_video_decoder_src_query_default;
  klass->transform_meta = gst_video_decoder_transform_meta_default;
}

static void
gst_video_decoder_init (GstVideoDecoder * decoder, GstVideoDecoderClass * klass)
{
  GstPadTemplate *pad_template;
  GstPad *pad;

  GST_DEBUG_OBJECT (decoder, "gst_video_decoder_init");

  decoder->priv = GST_VIDEO_DECODER_GET_PRIVATE (decoder);

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

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

  gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_video_decoder_chain));
  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_decoder_sink_event));
  gst_pad_set_query_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_decoder_sink_query));
  gst_element_add_pad (GST_ELEMENT (decoder), decoder->sinkpad);

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

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

  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_decoder_src_event));
  gst_pad_set_query_function (pad,
      GST_DEBUG_FUNCPTR (gst_video_decoder_src_query));
  gst_element_add_pad (GST_ELEMENT (decoder), decoder->srcpad);

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

  g_rec_mutex_init (&decoder->stream_lock);

  decoder->priv->input_adapter = gst_adapter_new ();
  decoder->priv->output_adapter = gst_adapter_new ();
  decoder->priv->packetized = TRUE;
  decoder->priv->needs_format = FALSE;

  decoder->priv->min_latency = 0;
  decoder->priv->max_latency = 0;

  gst_video_decoder_reset (decoder, TRUE, TRUE);
}

static GstVideoCodecState *
_new_input_state (GstCaps * caps)
{
  GstVideoCodecState *state;
  GstStructure *structure;
  const GValue *codec_data;

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

  structure = gst_caps_get_structure (caps, 0);

  codec_data = gst_structure_get_value (structure, "codec_data");
  if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER)
    state->codec_data = GST_BUFFER (g_value_dup_boxed (codec_data));

  return state;

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

static GstVideoCodecState *
_new_output_state (GstVideoFormat fmt, guint width, guint height,
    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, fmt, width, height)) {
    g_slice_free (GstVideoCodecState, state);
    return NULL;
  }

  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;
    /* only copy values that are not unknown so that we don't override the
     * defaults. subclasses should really fill these in when they know. */
    if (ref->chroma_site)
      tgt->chroma_site = ref->chroma_site;
    if (ref->colorimetry.range)
      tgt->colorimetry.range = ref->colorimetry.range;
    if (ref->colorimetry.matrix)
      tgt->colorimetry.matrix = ref->colorimetry.matrix;
    if (ref->colorimetry.transfer)
      tgt->colorimetry.transfer = ref->colorimetry.transfer;
    if (ref->colorimetry.primaries)
      tgt->colorimetry.primaries = ref->colorimetry.primaries;
    GST_DEBUG ("reference par %d/%d fps %d/%d",
        ref->par_n, ref->par_d, ref->fps_n, ref->fps_d);
    tgt->par_n = ref->par_n;
    tgt->par_d = ref->par_d;
    tgt->fps_n = ref->fps_n;
    tgt->fps_d = ref->fps_d;
    tgt->views = ref->views;

    GST_VIDEO_INFO_FIELD_ORDER (tgt) = GST_VIDEO_INFO_FIELD_ORDER (ref);

    if (GST_VIDEO_INFO_MULTIVIEW_MODE (ref) != GST_VIDEO_MULTIVIEW_MODE_NONE) {
      GST_VIDEO_INFO_MULTIVIEW_MODE (tgt) = GST_VIDEO_INFO_MULTIVIEW_MODE (ref);
      GST_VIDEO_INFO_MULTIVIEW_FLAGS (tgt) =
          GST_VIDEO_INFO_MULTIVIEW_FLAGS (ref);
    } else {
      /* Default to MONO, overridden as needed by sub-classes */
      GST_VIDEO_INFO_MULTIVIEW_MODE (tgt) = GST_VIDEO_MULTIVIEW_MODE_MONO;
      GST_VIDEO_INFO_MULTIVIEW_FLAGS (tgt) = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
    }
  }

  GST_DEBUG ("reference par %d/%d fps %d/%d",
      state->info.par_n, state->info.par_d,
      state->info.fps_n, state->info.fps_d);

  return state;
}

static gboolean
gst_video_decoder_setcaps (GstVideoDecoder * decoder, GstCaps * caps)
{
  GstVideoDecoderClass *decoder_class;
  GstVideoCodecState *state;
  gboolean ret = TRUE;

  decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);

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

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);

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

  state = _new_input_state (caps);

  if (G_UNLIKELY (state == NULL))
    goto parse_fail;

  if (decoder_class->set_format)
    ret = decoder_class->set_format (decoder, state);

  if (!ret)
    goto refused_format;

  if (decoder->priv->input_state)
    gst_video_codec_state_unref (decoder->priv->input_state);
  decoder->priv->input_state = state;

  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return ret;

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

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

refused_format:
  {
    GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
    GST_WARNING_OBJECT (decoder, "Subclass refused caps");
    gst_video_codec_state_unref (state);
    return FALSE;
  }
}

static void
gst_video_decoder_finalize (GObject * object)
{
  GstVideoDecoder *decoder;

  decoder = GST_VIDEO_DECODER (object);

  GST_DEBUG_OBJECT (object, "finalize");

  g_rec_mutex_clear (&decoder->stream_lock);

  if (decoder->priv->input_adapter) {
    g_object_unref (decoder->priv->input_adapter);
    decoder->priv->input_adapter = NULL;
  }
  if (decoder->priv->output_adapter) {
    g_object_unref (decoder->priv->output_adapter);
    decoder->priv->output_adapter = NULL;
  }

  if (decoder->priv->input_state)
    gst_video_codec_state_unref (decoder->priv->input_state);
  if (decoder->priv->output_state)
    gst_video_codec_state_unref (decoder->priv->output_state);

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

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

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

/* hard == FLUSH, otherwise discont */
static GstFlowReturn
gst_video_decoder_flush (GstVideoDecoder * dec, gboolean hard)
{
  GstVideoDecoderClass *klass = GST_VIDEO_DECODER_GET_CLASS (dec);
  GstFlowReturn ret = GST_FLOW_OK;

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

  /* Inform subclass */
  if (klass->reset) {
    GST_FIXME_OBJECT (dec, "GstVideoDecoder::reset() is deprecated");
    klass->reset (dec, hard);
  }

  if (klass->flush)
    klass->flush (dec);

  /* and get (re)set for the sequel */
  gst_video_decoder_reset (dec, FALSE, hard);

  return ret;
}

static GstEvent *
gst_video_decoder_create_merged_tags_event (GstVideoDecoder * dec)
{
  GstTagList *merged_tags;

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

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

  GST_DEBUG_OBJECT (dec, "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 gboolean
gst_video_decoder_push_event (GstVideoDecoder * decoder, GstEvent * event)
{
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      GstSegment segment;

      gst_event_copy_segment (event, &segment);

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

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

      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      decoder->output_segment = segment;
      decoder->priv->in_out_segment_sync =
          gst_segment_is_equal (&decoder->input_segment, &segment);
      decoder->priv->last_timestamp_out = GST_CLOCK_TIME_NONE;
      decoder->priv->earliest_time = GST_CLOCK_TIME_NONE;
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
      break;
    }
    default:
      break;
  }

  GST_DEBUG_OBJECT (decoder, "pushing event %s",
      gst_event_type_get_name (GST_EVENT_TYPE (event)));

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

static GstFlowReturn
gst_video_decoder_parse_available (GstVideoDecoder * dec, gboolean at_eos,
    gboolean new_buffer)
{
  GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_GET_CLASS (dec);
  GstVideoDecoderPrivate *priv = dec->priv;
  GstFlowReturn ret = GST_FLOW_OK;
  gsize was_available, available;
  guint inactive = 0;

  available = gst_adapter_available (priv->input_adapter);

  while (available || new_buffer) {
    new_buffer = FALSE;
    /* current frame may have been parsed and handled,
     * so we need to set up a new one when asking subclass to parse */
    if (priv->current_frame == NULL)
      priv->current_frame = gst_video_decoder_new_frame (dec);

    was_available = available;
    ret = decoder_class->parse (dec, priv->current_frame,
        priv->input_adapter, at_eos);
    if (ret != GST_FLOW_OK)
      break;

    /* if the subclass returned success (GST_FLOW_OK), it is expected
     * to have collected and submitted a frame, i.e. it should have
     * called gst_video_decoder_have_frame(), or at least consumed a
     * few bytes through gst_video_decoder_add_to_frame().
     *
     * Otherwise, this is an implementation bug, and we error out
     * after 2 failed attempts */
    available = gst_adapter_available (priv->input_adapter);
    if (!priv->current_frame || available != was_available)
      inactive = 0;
    else if (++inactive == 2)
      goto error_inactive;
  }

  return ret;

  /* ERRORS */
error_inactive:
  {
    GST_ERROR_OBJECT (dec, "Failed to consume data. Error in subclass?");
    return GST_FLOW_ERROR;
  }
}

/* This function has to be called with the stream lock taken. */
static GstFlowReturn
gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos)
{
  GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_GET_CLASS (dec);
  GstVideoDecoderPrivate *priv = dec->priv;
  GstFlowReturn ret = GST_FLOW_OK;

  if (dec->input_segment.rate > 0.0) {
    /* Forward mode, if unpacketized, give the child class
     * a final chance to flush out packets */
    if (!priv->packetized) {
      ret = gst_video_decoder_parse_available (dec, TRUE, FALSE);
    }

    if (at_eos) {
      if (decoder_class->finish)
        ret = decoder_class->finish (dec);
    } else {
      if (decoder_class->drain) {
        ret = decoder_class->drain (dec);
      } else {
        GST_FIXME_OBJECT (dec, "Sub-class should implement drain()");
      }
    }
  } else {
    /* Reverse playback mode */
    ret = gst_video_decoder_flush_parse (dec, TRUE);
  }

  return ret;
}

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;
}

/* Must be called holding the GST_VIDEO_DECODER_STREAM_LOCK */
static gboolean
gst_video_decoder_negotiate_default_caps (GstVideoDecoder * decoder)
{
  GstCaps *caps, *templcaps;
  GstVideoCodecState *state;
  GstVideoInfo info;
  gint i;
  gint caps_size;
  GstStructure *structure;

  templcaps = gst_pad_get_pad_template_caps (decoder->srcpad);
  caps = gst_pad_peer_query_caps (decoder->srcpad, templcaps);
  if (caps)
    gst_caps_unref (templcaps);
  else
    caps = templcaps;
  templcaps = NULL;

  if (!caps || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
    goto caps_error;

  GST_LOG_OBJECT (decoder, "peer caps %" GST_PTR_FORMAT, caps);

  /* before fixating, try to use whatever upstream provided */
  caps = gst_caps_make_writable (caps);
  caps_size = gst_caps_get_size (caps);
  if (decoder->priv->input_state && decoder->priv->input_state->caps) {
    GstCaps *sinkcaps = decoder->priv->input_state->caps;
    GstStructure *structure = gst_caps_get_structure (sinkcaps, 0);
    gint width, height;
    gint par_n, par_d;
    gint fps_n, fps_d;

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

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

    if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i), "framerate",
            GST_TYPE_FRACTION, fps_n, fps_d, NULL);
      }
    }

    if (gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n,
            &par_d)) {
      for (i = 0; i < caps_size; i++) {
        gst_structure_set (gst_caps_get_structure (caps, i),
            "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
      }
    }
  }

  for (i = 0; i < caps_size; i++) {
    structure = gst_caps_get_structure (caps, i);
    /* Random I420 1280x720@30 for fixation */
    if (gst_structure_has_field (structure, "format"))
      gst_structure_fixate_field_string (structure, "format", "I420");
    else
      gst_structure_set (structure, "format", G_TYPE_STRING, "I420", NULL);

    if (gst_structure_has_field (structure, "width"))
      gst_structure_fixate_field_nearest_int (structure, "width", 1280);
    else
      gst_structure_set (structure, "width", G_TYPE_INT, 1280, NULL);

    if (gst_structure_has_field (structure, "height"))
      gst_structure_fixate_field_nearest_int (structure, "height", 720);
    else
      gst_structure_set (structure, "height", G_TYPE_INT, 720, NULL);

    if (gst_structure_has_field (structure, "framerate"))
      gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30,
          1);
    else
      gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, 30, 1,
          NULL);

    if (gst_structure_has_field (structure, "pixel-aspect-ratio"))
      gst_structure_fixate_field_nearest_fraction (structure,
          "pixel-aspect-ratio", 1, 1);
    else
      gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION,
          1, 1, NULL);
  }
  caps = gst_caps_fixate (caps);
  structure = gst_caps_get_structure (caps, 0);

  if (!caps || !gst_video_info_from_caps (&info, caps))
    goto caps_error;

  GST_INFO_OBJECT (decoder,
      "Chose default caps %" GST_PTR_FORMAT " for initial gap", caps);
  state =
      gst_video_decoder_set_output_state (decoder, info.finfo->format,
      info.width, info.height, decoder->priv->input_state);
  gst_video_codec_state_unref (state);
  gst_caps_unref (caps);

  return TRUE;

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

static gboolean
gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
    GstEvent * event)
{
  GstVideoDecoderPrivate *priv;
  gboolean ret = FALSE;
  gboolean forward_immediate = FALSE;

  priv = decoder->priv;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_STREAM_START:
    {
      GstFlowReturn flow_ret = GST_FLOW_OK;

      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
      ret = (flow_ret == GST_FLOW_OK);

      GST_DEBUG_OBJECT (decoder, "received STREAM_START. Clearing taglist");
      /* Flush upstream tags after a STREAM_START */
      if (priv->upstream_tags) {
        gst_tag_list_unref (priv->upstream_tags);
        priv->upstream_tags = NULL;
        priv->tags_changed = TRUE;
      }
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

      /* Forward STREAM_START immediately. Everything is drained after
       * the STREAM_START event and we can forward this event immediately
       * now without having buffers out of order.
       */
      forward_immediate = TRUE;
      break;
    }
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_video_decoder_setcaps (decoder, caps);
      gst_event_unref (event);
      event = NULL;
      break;
    }
    case GST_EVENT_SEGMENT_DONE:
    {
      GstFlowReturn flow_ret = GST_FLOW_OK;

      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      flow_ret = gst_video_decoder_drain_out (decoder, TRUE);
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
      ret = (flow_ret == GST_FLOW_OK);

      /* Forward SEGMENT_DONE immediately. This is required
       * because no buffer or serialized event might come
       * after SEGMENT_DONE and nothing could trigger another
       * _finish_frame() call.
       *
       * The subclass can override this behaviour by overriding
       * the ::sink_event() vfunc and not chaining up to the
       * parent class' ::sink_event() until a later time.
       */
      forward_immediate = TRUE;
      break;
    }
    case GST_EVENT_EOS:
    {
      GstFlowReturn flow_ret = GST_FLOW_OK;

      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      flow_ret = gst_video_decoder_drain_out (decoder, TRUE);
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
      ret = (flow_ret == GST_FLOW_OK);

      /* Error out even if EOS was ok when we had input, but no output */
      if (ret && priv->had_input_data && !priv->had_output_data) {
        GST_ELEMENT_ERROR (decoder, STREAM, DECODE,
            ("No valid frames decoded before end of stream"),
            ("no valid frames found"));
      }

      /* Forward EOS immediately. This is required because no
       * buffer or serialized event will come after EOS and
       * nothing could trigger another _finish_frame() call.
       *
       * The subclass can override this behaviour by overriding
       * the ::sink_event() vfunc and not chaining up to the
       * parent class' ::sink_event() until a later time.
       */
      forward_immediate = TRUE;
      break;
    }
    case GST_EVENT_GAP:
    {
      GstFlowReturn flow_ret = GST_FLOW_OK;
      gboolean needs_reconfigure = FALSE;
      GList *events;
      GList *frame_events;

      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
      ret = (flow_ret == GST_FLOW_OK);

      /* Ensure we have caps before forwarding the event */
      if (!decoder->priv->output_state) {
        if (!gst_video_decoder_negotiate_default_caps (decoder)) {
          GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
          GST_ELEMENT_ERROR (decoder, STREAM, FORMAT, (NULL),
              ("Decoder output not negotiated before GAP event."));
          forward_immediate = TRUE;
          break;
        }
        needs_reconfigure = TRUE;
      }

      needs_reconfigure = gst_pad_check_reconfigure (decoder->srcpad)
          || needs_reconfigure;
      if (decoder->priv->output_state_changed || needs_reconfigure) {
        if (!gst_video_decoder_negotiate_unlocked (decoder)) {
          GST_WARNING_OBJECT (decoder, "Failed to negotiate with downstream");
          gst_pad_mark_reconfigure (decoder->srcpad);
        }
      }

      GST_DEBUG_OBJECT (decoder, "Pushing all pending serialized events"
          " before the gap");
      events = decoder->priv->pending_events;
      frame_events = decoder->priv->current_frame_events;
      decoder->priv->pending_events = NULL;
      decoder->priv->current_frame_events = NULL;

      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

      gst_video_decoder_push_event_list (decoder, events);
      gst_video_decoder_push_event_list (decoder, frame_events);

      /* Forward GAP immediately. Everything is drained after
       * the GAP event and we can forward this event immediately
       * now without having buffers out of order.
       */
      forward_immediate = TRUE;
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      gboolean in_still;
      GstFlowReturn flow_ret = GST_FLOW_OK;

      if (gst_video_event_parse_still_frame (event, &in_still)) {
        if (in_still) {
          GST_DEBUG_OBJECT (decoder, "draining current data for still-frame");
          GST_VIDEO_DECODER_STREAM_LOCK (decoder);
          flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
          GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
          ret = (flow_ret == GST_FLOW_OK);
        }
        /* Forward STILL_FRAME immediately. Everything is drained after
         * the STILL_FRAME event and we can forward this event immediately
         * now without having buffers out of order.
         */
        forward_immediate = TRUE;
      }
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment segment;

      gst_event_copy_segment (event, &segment);

      if (segment.format == GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (decoder,
            "received TIME SEGMENT %" GST_SEGMENT_FORMAT, &segment);
      } else {
        gint64 start;

        GST_DEBUG_OBJECT (decoder,
            "received SEGMENT %" GST_SEGMENT_FORMAT, &segment);

        /* handle newsegment as a result from our legacy simple seeking */
        /* note that initial 0 should convert to 0 in any case */
        if (priv->do_estimate_rate &&
            gst_pad_query_convert (decoder->sinkpad, GST_FORMAT_BYTES,
                segment.start, GST_FORMAT_TIME, &start)) {
          /* best attempt convert */
          /* as these are only estimates, stop is kept open-ended to avoid
           * premature cutting */
          GST_DEBUG_OBJECT (decoder,
              "converted to TIME start %" GST_TIME_FORMAT,
              GST_TIME_ARGS (start));
          segment.start = start;
          segment.stop = GST_CLOCK_TIME_NONE;
          segment.time = start;
          /* replace event */
          gst_event_unref (event);
          event = gst_event_new_segment (&segment);
        } else {
          goto newseg_wrong_format;
        }
      }

      GST_VIDEO_DECODER_STREAM_LOCK (decoder);

      priv->base_timestamp = GST_CLOCK_TIME_NONE;
      priv->base_picture_number = 0;

      decoder->input_segment = segment;
      decoder->priv->in_out_segment_sync = FALSE;

      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
    {
      GList *l;

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

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

      /* well, this is kind of worse than a DISCONT */
      gst_video_decoder_flush (decoder, TRUE);
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
      /* Forward FLUSH_STOP immediately. This is required because it is
       * expected to be forwarded immediately and no buffers are queued
       * anyway.
       */
      forward_immediate = TRUE;
      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_DECODER_STREAM_LOCK (decoder);
        if (priv->upstream_tags != tags) {
          if (priv->upstream_tags)
            gst_tag_list_unref (priv->upstream_tags);
          priv->upstream_tags = gst_tag_list_ref (tags);
          GST_INFO_OBJECT (decoder, "upstream tags: %" GST_PTR_FORMAT, tags);
        }
        gst_event_unref (event);
        event = gst_video_decoder_create_merged_tags_event (decoder);
        GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
        if (!event)
          ret = TRUE;
      }
      break;
    }
    default:
      break;
  }

  /* Forward non-serialized events immediately, and all other
   * events which can be forwarded immediately without potentially
   * causing the event to go out of order with other events and
   * buffers as decided above.
   */
  if (event) {
    if (!GST_EVENT_IS_SERIALIZED (event) || forward_immediate) {
      ret = gst_video_decoder_push_event (decoder, event);
    } else {
      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      decoder->priv->current_frame_events =
          g_list_prepend (decoder->priv->current_frame_events, event);
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
      ret = TRUE;
    }
  }

  return ret;

newseg_wrong_format:
  {
    GST_DEBUG_OBJECT (decoder, "received non TIME newsegment");
    gst_event_unref (event);
    /* SWALLOW EVENT */
    return TRUE;
  }
}

static gboolean
gst_video_decoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstVideoDecoder *decoder;
  GstVideoDecoderClass *decoder_class;
  gboolean ret = FALSE;

  decoder = GST_VIDEO_DECODER (parent);
  decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);

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

  if (decoder_class->sink_event)
    ret = decoder_class->sink_event (decoder, event);

  return ret;
}

/* perform upstream byte <-> time conversion (duration, seeking)
 * if subclass allows and if enough data for moderately decent conversion */
static inline gboolean
gst_video_decoder_do_byte (GstVideoDecoder * dec)
{
  gboolean ret;

  GST_OBJECT_LOCK (dec);
  ret = dec->priv->do_estimate_rate && (dec->priv->bytes_out > 0)
      && (dec->priv->time > GST_SECOND);
  GST_OBJECT_UNLOCK (dec);

  return ret;
}

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

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

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

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

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

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

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

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

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

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

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

static gboolean
gst_video_decoder_src_event_default (GstVideoDecoder * decoder,
    GstEvent * event)
{
  GstVideoDecoderPrivate *priv;
  gboolean res = FALSE;

  priv = decoder->priv;

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

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

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

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

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

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

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

      res = gst_pad_push_event (decoder->sinkpad, event);
      break;
    }
    case GST_EVENT_QOS:
    {
      GstQOSType type;
      gdouble proportion;
      GstClockTimeDiff diff;
      GstClockTime timestamp;

      gst_event_parse_qos (event, &type, &proportion, &diff, &timestamp);

      GST_OBJECT_LOCK (decoder);
      priv->proportion = proportion;
      if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) {
        if (G_UNLIKELY (diff > 0)) {
          priv->earliest_time = timestamp + 2 * diff + priv->qos_frame_duration;
        } else {
          priv->earliest_time = timestamp + diff;
        }
      } else {
        priv->earliest_time = GST_CLOCK_TIME_NONE;
      }
      GST_OBJECT_UNLOCK (decoder);

      GST_DEBUG_OBJECT (decoder,
          "got QoS %" GST_TIME_FORMAT ", %" GST_STIME_FORMAT ", %g",
          GST_TIME_ARGS (timestamp), GST_STIME_ARGS (diff), proportion);

      res = gst_pad_push_event (decoder->sinkpad, event);
      break;
    }
    default:
      res = gst_pad_push_event (decoder->sinkpad, event);
      break;
  }
done:
  return res;

convert_error:
  GST_DEBUG_OBJECT (decoder, "could not convert format");
  goto done;
}

static gboolean
gst_video_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstVideoDecoder *decoder;
  GstVideoDecoderClass *decoder_class;
  gboolean ret = FALSE;

  decoder = GST_VIDEO_DECODER (parent);
  decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);

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

  if (decoder_class->src_event)
    ret = decoder_class->src_event (decoder, event);

  return ret;
}

static gboolean
gst_video_decoder_src_query_default (GstVideoDecoder * dec, GstQuery * query)
{
  GstPad *pad = GST_VIDEO_DECODER_SRC_PAD (dec);
  gboolean res = TRUE;

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

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;
      gint64 time, value;

      /* upstream gets a chance first */
      if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
        GST_LOG_OBJECT (dec, "returning peer response");
        break;
      }

      /* Refuse BYTES format queries. If it made sense to
       * answer them, upstream would have already */
      gst_query_parse_position (query, &format, NULL);

      if (format == GST_FORMAT_BYTES) {
        GST_LOG_OBJECT (dec, "Ignoring BYTES position query");
        break;
      }

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

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

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

      gst_query_set_position (query, format, value);

      GST_LOG_OBJECT (dec,
          "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
          format);
      break;
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;

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

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

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

      GST_DEBUG_OBJECT (dec, "convert query");

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      GST_OBJECT_LOCK (dec);
      if (dec->priv->output_state != NULL)
        res = __gst_video_rawvideo_convert (dec->priv->output_state,
            src_fmt, src_val, &dest_fmt, &dest_val);
      else
        res = FALSE;
      GST_OBJECT_UNLOCK (dec);
      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 (dec->sinkpad, query);
      if (res) {
        gst_query_parse_latency (query, &live, &min_latency, &max_latency);
        GST_DEBUG_OBJECT (dec, "Peer qlatency: live %d, min %"
            GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
            GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));

        GST_OBJECT_LOCK (dec);
        min_latency += dec->priv->min_latency;
        if (max_latency == GST_CLOCK_TIME_NONE
            || dec->priv->max_latency == GST_CLOCK_TIME_NONE)
          max_latency = GST_CLOCK_TIME_NONE;
        else
          max_latency += dec->priv->max_latency;
        GST_OBJECT_UNLOCK (dec);

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

error:
  GST_ERROR_OBJECT (dec, "query failed");
  return res;
}

static gboolean
gst_video_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstVideoDecoder *decoder;
  GstVideoDecoderClass *decoder_class;
  gboolean ret = FALSE;

  decoder = GST_VIDEO_DECODER (parent);
  decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);

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

  if (decoder_class->src_query)
    ret = decoder_class->src_query (decoder, query);

  return ret;
}

/**
 * gst_video_decoder_proxy_getcaps:
 * @decoder: a #GstVideoDecoder
 * @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.
 *
 * Returns: (transfer full): a #GstCaps owned by caller
 *
 * Since: 1.6
 */
GstCaps *
gst_video_decoder_proxy_getcaps (GstVideoDecoder * decoder, GstCaps * caps,
    GstCaps * filter)
{
  return __gst_video_element_proxy_getcaps (GST_ELEMENT_CAST (decoder),
      GST_VIDEO_DECODER_SINK_PAD (decoder),
      GST_VIDEO_DECODER_SRC_PAD (decoder), caps, filter);
}

static GstCaps *
gst_video_decoder_sink_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
{
  GstVideoDecoderClass *klass;
  GstCaps *caps;

  klass = GST_VIDEO_DECODER_GET_CLASS (decoder);

  if (klass->getcaps)
    caps = klass->getcaps (decoder, filter);
  else
    caps = gst_video_decoder_proxy_getcaps (decoder, NULL, filter);

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

  return caps;
}

static gboolean
gst_video_decoder_sink_query_default (GstVideoDecoder * decoder,
    GstQuery * query)
{
  GstPad *pad = GST_VIDEO_DECODER_SINK_PAD (decoder);
  GstVideoDecoderPrivate *priv;
  gboolean res = FALSE;

  priv = decoder->priv;

  GST_LOG_OBJECT (decoder, "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 (decoder);
      res =
          __gst_video_encoded_video_convert (priv->bytes_out, priv->time,
          src_fmt, src_val, &dest_fmt, &dest_val);
      GST_OBJECT_UNLOCK (decoder);
      if (!res)
        goto error;
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
    case GST_QUERY_ALLOCATION:{
      GstVideoDecoderClass *klass = GST_VIDEO_DECODER_GET_CLASS (decoder);

      if (klass->propose_allocation)
        res = klass->propose_allocation (decoder, query);
      break;
    }
    case GST_QUERY_CAPS:{
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_video_decoder_sink_getcaps (decoder, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    case GST_QUERY_ACCEPT_CAPS:{
      if (decoder->priv->use_default_pad_acceptcaps) {
        res =
            gst_pad_query_default (GST_VIDEO_DECODER_SINK_PAD (decoder),
            GST_OBJECT_CAST (decoder), query);
      } else {
        GstCaps *caps;
        GstCaps *allowed_caps;
        GstCaps *template_caps;
        gboolean accept;

        gst_query_parse_accept_caps (query, &caps);

        template_caps = gst_pad_get_pad_template_caps (pad);
        accept = gst_caps_is_subset (caps, template_caps);
        gst_caps_unref (template_caps);

        if (accept) {
          allowed_caps =
              gst_pad_query_caps (GST_VIDEO_DECODER_SINK_PAD (decoder), caps);

          accept = gst_caps_can_intersect (caps, allowed_caps);

          gst_caps_unref (allowed_caps);
        }

        gst_query_set_accept_caps_result (query, accept);
        res = TRUE;
      }
      break;
    }
    default:
      res = gst_pad_query_default (pad, GST_OBJECT (decoder), query);
      break;
  }
done:

  return res;
error:
  GST_DEBUG_OBJECT (decoder, "query failed");
  goto done;

}

static gboolean
gst_video_decoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstVideoDecoder *decoder;
  GstVideoDecoderClass *decoder_class;
  gboolean ret = FALSE;

  decoder = GST_VIDEO_DECODER (parent);
  decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);

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

  if (decoder_class->sink_query)
    ret = decoder_class->sink_query (decoder, query);

  return ret;
}

typedef struct _Timestamp Timestamp;
struct _Timestamp
{
  guint64 offset;
  GstClockTime pts;
  GstClockTime dts;
  GstClockTime duration;
  guint flags;
};

static void
timestamp_free (Timestamp * ts)
{
  g_slice_free (Timestamp, ts);
}

static void
gst_video_decoder_add_buffer_info (GstVideoDecoder * decoder,
    GstBuffer * buffer)
{
  GstVideoDecoderPrivate *priv = decoder->priv;
  Timestamp *ts;

  if (!GST_BUFFER_PTS_IS_VALID (buffer) &&
      !GST_BUFFER_DTS_IS_VALID (buffer) &&
      !GST_BUFFER_DURATION_IS_VALID (buffer) &&
      GST_BUFFER_FLAGS (buffer) == 0) {
    /* Save memory - don't bother storing info
     * for buffers with no distinguishing info */
    return;
  }

  ts = g_slice_new (Timestamp);

  GST_LOG_OBJECT (decoder,
      "adding PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT
      " (offset:%" G_GUINT64_FORMAT ")",
      GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
      GST_TIME_ARGS (GST_BUFFER_DTS (buffer)), priv->input_offset);

  ts->offset = priv->input_offset;
  ts->pts = GST_BUFFER_PTS (buffer);
  ts->dts = GST_BUFFER_DTS (buffer);
  ts->duration = GST_BUFFER_DURATION (buffer);
  ts->flags = GST_BUFFER_FLAGS (buffer);

  priv->timestamps = g_list_append (priv->timestamps, ts);
}

static void
gst_video_decoder_get_buffer_info_at_offset (GstVideoDecoder *
    decoder, guint64 offset, GstClockTime * pts, GstClockTime * dts,
    GstClockTime * duration, guint * flags)
{
#ifndef GST_DISABLE_GST_DEBUG
  guint64 got_offset = 0;
#endif
  Timestamp *ts;
  GList *g;

  *pts = GST_CLOCK_TIME_NONE;
  *dts = GST_CLOCK_TIME_NONE;
  *duration = GST_CLOCK_TIME_NONE;
  *flags = 0;

  g = decoder->priv->timestamps;
  while (g) {
    ts = g->data;
    if (ts->offset <= offset) {
#ifndef GST_DISABLE_GST_DEBUG
      got_offset = ts->offset;
#endif
      *pts = ts->pts;
      *dts = ts->dts;
      *duration = ts->duration;
      *flags = ts->flags;
      g = g->next;
      decoder->priv->timestamps = g_list_remove (decoder->priv->timestamps, ts);
      timestamp_free (ts);
    } else {
      break;
    }
  }

  GST_LOG_OBJECT (decoder,
      "got PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT " flags %x @ offs %"
      G_GUINT64_FORMAT " (wanted offset:%" G_GUINT64_FORMAT ")",
      GST_TIME_ARGS (*pts), GST_TIME_ARGS (*dts), *flags, got_offset, offset);
}

static void
gst_video_decoder_clear_queues (GstVideoDecoder * dec)
{
  GstVideoDecoderPrivate *priv = dec->priv;

  g_list_free_full (priv->output_queued,
      (GDestroyNotify) gst_mini_object_unref);
  priv->output_queued = NULL;

  g_list_free_full (priv->gather, (GDestroyNotify) gst_mini_object_unref);
  priv->gather = NULL;
  g_list_free_full (priv->decode, (GDestroyNotify) gst_video_codec_frame_unref);
  priv->decode = NULL;
  g_list_free_full (priv->parse, (GDestroyNotify) gst_mini_object_unref);
  priv->parse = NULL;
  g_list_free_full (priv->parse_gather,
      (GDestroyNotify) gst_video_codec_frame_unref);
  priv->parse_gather = NULL;
  g_list_free_full (priv->frames, (GDestroyNotify) gst_video_codec_frame_unref);
  priv->frames = NULL;
}

static void
gst_video_decoder_reset (GstVideoDecoder * decoder, gboolean full,
    gboolean flush_hard)
{
  GstVideoDecoderPrivate *priv = decoder->priv;

  GST_DEBUG_OBJECT (decoder, "reset full %d", full);

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);

  if (full || flush_hard) {
    gst_segment_init (&decoder->input_segment, GST_FORMAT_UNDEFINED);
    gst_segment_init (&decoder->output_segment, GST_FORMAT_UNDEFINED);
    gst_video_decoder_clear_queues (decoder);
    decoder->priv->in_out_segment_sync = TRUE;

    if (priv->current_frame) {
      gst_video_codec_frame_unref (priv->current_frame);
      priv->current_frame = NULL;
    }

    g_list_free_full (priv->current_frame_events,
        (GDestroyNotify) gst_event_unref);
    priv->current_frame_events = NULL;
    g_list_free_full (priv->pending_events, (GDestroyNotify) gst_event_unref);
    priv->pending_events = NULL;

    priv->error_count = 0;
    priv->max_errors = GST_VIDEO_DECODER_MAX_ERRORS;
    priv->had_output_data = FALSE;
    priv->had_input_data = FALSE;

    GST_OBJECT_LOCK (decoder);
    priv->earliest_time = GST_CLOCK_TIME_NONE;
    priv->proportion = 0.5;
    GST_OBJECT_UNLOCK (decoder);
  }

  if (full) {
    if (priv->input_state)
      gst_video_codec_state_unref (priv->input_state);
    priv->input_state = NULL;
    GST_OBJECT_LOCK (decoder);
    if (priv->output_state)
      gst_video_codec_state_unref (priv->output_state);
    priv->output_state = NULL;

    priv->qos_frame_duration = 0;
    GST_OBJECT_UNLOCK (decoder);

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

    priv->dropped = 0;
    priv->processed = 0;

    priv->decode_frame_number = 0;
    priv->base_picture_number = 0;

    if (priv->pool) {
      GST_DEBUG_OBJECT (decoder, "deactivate pool %" GST_PTR_FORMAT,
          priv->pool);
      gst_buffer_pool_set_active (priv->pool, FALSE);
      gst_object_unref (priv->pool);
      priv->pool = NULL;
    }

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

  priv->discont = TRUE;

  priv->base_timestamp = GST_CLOCK_TIME_NONE;
  priv->last_timestamp_out = GST_CLOCK_TIME_NONE;
  priv->pts_delta = GST_CLOCK_TIME_NONE;

  priv->input_offset = 0;
  priv->frame_offset = 0;
  gst_adapter_clear (priv->input_adapter);
  gst_adapter_clear (priv->output_adapter);
  g_list_free_full (priv->timestamps, (GDestroyNotify) timestamp_free);
  priv->timestamps = NULL;

  GST_OBJECT_LOCK (decoder);
  priv->bytes_out = 0;
  priv->time = 0;
  GST_OBJECT_UNLOCK (decoder);

#ifndef GST_DISABLE_DEBUG
  priv->last_reset_time = gst_util_get_timestamp ();
#endif

  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
}

static GstFlowReturn
gst_video_decoder_chain_forward (GstVideoDecoder * decoder,
    GstBuffer * buf, gboolean at_eos)
{
  GstVideoDecoderPrivate *priv;
  GstVideoDecoderClass *klass;
  GstFlowReturn ret = GST_FLOW_OK;

  klass = GST_VIDEO_DECODER_GET_CLASS (decoder);
  priv = decoder->priv;

  g_return_val_if_fail (priv->packetized || klass->parse, GST_FLOW_ERROR);

  /* Draining on DISCONT is handled in chain_reverse() for reverse playback,
   * and this function would only be called to get everything collected GOP
   * by GOP in the parse_gather list */
  if (decoder->input_segment.rate > 0.0 && GST_BUFFER_IS_DISCONT (buf))
    ret = gst_video_decoder_drain_out (decoder, FALSE);

  if (priv->current_frame == NULL)
    priv->current_frame = gst_video_decoder_new_frame (decoder);

  if (!priv->packetized)
    gst_video_decoder_add_buffer_info (decoder, buf);

  priv->input_offset += gst_buffer_get_size (buf);

  if (priv->packetized) {
    gboolean was_keyframe = FALSE;
    if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
      was_keyframe = TRUE;
      GST_LOG_OBJECT (decoder, "Marking current_frame as sync point");
      GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (priv->current_frame);
    }

    priv->current_frame->input_buffer = buf;

    if (decoder->input_segment.rate < 0.0) {
      priv->parse_gather =
          g_list_prepend (priv->parse_gather, priv->current_frame);
    } else {
      ret = gst_video_decoder_decode_frame (decoder, priv->current_frame);
    }
    priv->current_frame = NULL;
    /* If in trick mode and it was a keyframe, drain decoder to avoid extra
     * latency. Only do this for forwards playback as reverse playback handles
     * draining on keyframes in flush_parse(), and would otherwise call back
     * from drain_out() to here causing an infinite loop.
     * Also this function is only called for reverse playback to gather frames
     * GOP by GOP, and does not do any actual decoding. That would be done by
     * flush_decode() */
    if (ret == GST_FLOW_OK && was_keyframe && decoder->input_segment.rate > 0.0
        && (decoder->input_segment.flags & GST_SEEK_FLAG_TRICKMODE_KEY_UNITS))
      ret = gst_video_decoder_drain_out (decoder, FALSE);
  } else {
    gst_adapter_push (priv->input_adapter, buf);

    ret = gst_video_decoder_parse_available (decoder, at_eos, TRUE);
  }

  if (ret == GST_VIDEO_DECODER_FLOW_NEED_DATA)
    return GST_FLOW_OK;

  return ret;
}

static GstFlowReturn
gst_video_decoder_flush_decode (GstVideoDecoder * dec)
{
  GstVideoDecoderPrivate *priv = dec->priv;
  GstFlowReturn res = GST_FLOW_OK;
  GList *walk;

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

  walk = priv->decode;
  while (walk) {
    GList *next;
    GstVideoCodecFrame *frame = (GstVideoCodecFrame *) (walk->data);

    GST_DEBUG_OBJECT (dec, "decoding frame %p buffer %p, PTS %" GST_TIME_FORMAT
        ", DTS %" GST_TIME_FORMAT, frame, frame->input_buffer,
        GST_TIME_ARGS (GST_BUFFER_PTS (frame->input_buffer)),
        GST_TIME_ARGS (GST_BUFFER_DTS (frame->input_buffer)));

    next = walk->next;

    priv->decode = g_list_delete_link (priv->decode, walk);

    /* decode buffer, resulting data prepended to queue */
    res = gst_video_decoder_decode_frame (dec, frame);
    if (res != GST_FLOW_OK)
      break;

    walk = next;
  }

  return res;
}

/* gst_video_decoder_flush_parse is called from the
 * chain_reverse() function when a buffer containing
 * a DISCONT - indicating that reverse playback
 * looped back to the next data block, and therefore
 * all available data should be fed through the
 * decoder and frames gathered for reversed output
 */
static GstFlowReturn
gst_video_decoder_flush_parse (GstVideoDecoder * dec, gboolean at_eos)
{
  GstVideoDecoderPrivate *priv = dec->priv;
  GstFlowReturn res = GST_FLOW_OK;
  GList *walk;
  GstVideoDecoderClass *decoder_class;

  decoder_class = GST_VIDEO_DECODER_GET_CLASS (dec);

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

  /* Reverse the gather list, and prepend it to the parse list,
   * then flush to parse whatever we can */
  priv->gather = g_list_reverse (priv->gather);
  priv->parse = g_list_concat (priv->gather, priv->parse);
  priv->gather = NULL;

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

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

    GST_DEBUG_OBJECT (dec, "parsing buffer %p, PTS %" GST_TIME_FORMAT
        ", DTS %" GST_TIME_FORMAT " flags %x", buf,
        GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
        GST_TIME_ARGS (GST_BUFFER_DTS (buf)), GST_BUFFER_FLAGS (buf));

    /* parse buffer, resulting frames prepended to parse_gather queue */
    gst_buffer_ref (buf);
    res = gst_video_decoder_chain_forward (dec, buf, at_eos);

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

  walk = priv->parse_gather;
  while (walk) {
    GstVideoCodecFrame *frame = (GstVideoCodecFrame *) (walk->data);
    GList *walk2;

    /* this is reverse playback, check if we need to apply some segment
     * to the output before decoding, as during decoding the segment.rate
     * must be used to determine if a buffer should be pushed or added to
     * the output list for reverse pushing.
     *
     * The new segment is not immediately pushed here because we must
     * wait for negotiation to happen before it can be pushed to avoid
     * pushing a segment before caps event. Negotiation only happens
     * when finish_frame is called.
     */
    for (walk2 = frame->events; walk2;) {
      GList *cur = walk2;
      GstEvent *event = walk2->data;

      walk2 = g_list_next (walk2);
      if (GST_EVENT_TYPE (event) <= GST_EVENT_SEGMENT) {

        if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
          GstSegment segment;

          GST_DEBUG_OBJECT (dec, "Segment at frame %p %" GST_TIME_FORMAT,
              frame, GST_TIME_ARGS (GST_BUFFER_PTS (frame->input_buffer)));
          gst_event_copy_segment (event, &segment);
          if (segment.format == GST_FORMAT_TIME) {
            dec->output_segment = segment;
            dec->priv->in_out_segment_sync =
                gst_segment_is_equal (&dec->input_segment, &segment);
          }
        }
        dec->priv->pending_events =
            g_list_append (dec->priv->pending_events, event);
        frame->events = g_list_delete_link (frame->events, cur);
      }
    }

    walk = walk->next;
  }

  /* now we can process frames. Start by moving each frame from the parse_gather
   * to the decode list, reverse the order as we go, and stopping when/if we
   * copy a keyframe. */
  GST_DEBUG_OBJECT (dec, "checking parsed frames for a keyframe to decode");
  walk = priv->parse_gather;
  while (walk) {
    GstVideoCodecFrame *frame = (GstVideoCodecFrame *) (walk->data);

    /* remove from the gather list */
    priv->parse_gather = g_list_remove_link (priv->parse_gather, walk);

    /* move it to the front of the decode queue */
    priv->decode = g_list_concat (walk, priv->decode);

    /* if we copied a keyframe, flush and decode the decode queue */
    if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
      GST_DEBUG_OBJECT (dec, "found keyframe %p with PTS %" GST_TIME_FORMAT
          ", DTS %" GST_TIME_FORMAT, frame,
          GST_TIME_ARGS (GST_BUFFER_PTS (frame->input_buffer)),
          GST_TIME_ARGS (GST_BUFFER_DTS (frame->input_buffer)));
      res = gst_video_decoder_flush_decode (dec);
      if (res != GST_FLOW_OK)
        goto done;

      /* We need to tell the subclass to drain now.
       * We prefer the drain vfunc, but for backward-compat
       * we use a finish() vfunc if drain isn't implemented */
      if (decoder_class->drain) {
        GST_DEBUG_OBJECT (dec, "Draining");
        res = decoder_class->drain (dec);
      } else if (decoder_class->finish) {
        GST_FIXME_OBJECT (dec, "Sub-class should implement drain(). "
            "Calling finish() for backwards-compat");
        res = decoder_class->finish (dec);
      }

      if (res != GST_FLOW_OK)
        goto done;

      /* now send queued data downstream */
      walk = priv->output_queued;
      while (walk) {
        GstBuffer *buf = GST_BUFFER_CAST (walk->data);

        if (G_LIKELY (res == GST_FLOW_OK)) {
          /* avoid stray DISCONT from forward processing,
           * which have no meaning in reverse pushing */
          GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);

          /* Last chance to calculate a timestamp as we loop backwards
           * through the list */
          if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE)
            priv->last_timestamp_out = GST_BUFFER_TIMESTAMP (buf);
          else if (priv->last_timestamp_out != GST_CLOCK_TIME_NONE &&
              GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE) {
            GST_BUFFER_TIMESTAMP (buf) =
                priv->last_timestamp_out - GST_BUFFER_DURATION (buf);
            priv->last_timestamp_out = GST_BUFFER_TIMESTAMP (buf);
            GST_LOG_OBJECT (dec,
                "Calculated TS %" GST_TIME_FORMAT " working backwards",
                GST_TIME_ARGS (priv->last_timestamp_out));
          }

          res = gst_video_decoder_clip_and_push_buf (dec, buf);
        } else {
          gst_buffer_unref (buf);
        }

        priv->output_queued =
            g_list_delete_link (priv->output_queued, priv->output_queued);
        walk = priv->output_queued;
      }

      /* clear buffer and decoder state again
       * before moving to the previous keyframe */
      gst_video_decoder_flush (dec, FALSE);
    }

    walk = priv->parse_gather;
  }

done:
  return res;
}

static GstFlowReturn
gst_video_decoder_chain_reverse (GstVideoDecoder * dec, GstBuffer * buf)
{
  GstVideoDecoderPrivate *priv = dec->priv;
  GstFlowReturn result = GST_FLOW_OK;

  /* if we have a discont, move buffers to the decode list */
  if (!buf || GST_BUFFER_IS_DISCONT (buf)) {
    GST_DEBUG_OBJECT (dec, "received discont");

    /* parse and decode stuff in the gather and parse queues */
    result = gst_video_decoder_flush_parse (dec, FALSE);
  }

  if (G_LIKELY (buf)) {
    GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %" G_GSIZE_FORMAT ", "
        "PTS %" GST_TIME_FORMAT ", DTS %" GST_TIME_FORMAT ", dur %"
        GST_TIME_FORMAT, buf, gst_buffer_get_size (buf),
        GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
        GST_TIME_ARGS (GST_BUFFER_DTS (buf)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));

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

  return result;
}

static GstFlowReturn
gst_video_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstVideoDecoder *decoder;
  GstFlowReturn ret = GST_FLOW_OK;

  decoder = GST_VIDEO_DECODER (parent);

  if (G_UNLIKELY (!decoder->priv->input_state && decoder->priv->needs_format))
    goto not_negotiated;

  GST_LOG_OBJECT (decoder,
      "chain PTS %" GST_TIME_FORMAT ", DTS %" GST_TIME_FORMAT " duration %"
      GST_TIME_FORMAT " size %" G_GSIZE_FORMAT " flags %x",
      GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
      GST_TIME_ARGS (GST_BUFFER_DTS (buf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
      gst_buffer_get_size (buf), GST_BUFFER_FLAGS (buf));

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);

  /* NOTE:
   * requiring the pad to be negotiated makes it impossible to use
   * oggdemux or filesrc ! decoder */

  if (decoder->input_segment.format == GST_FORMAT_UNDEFINED) {
    GstEvent *event;
    GstSegment *segment = &decoder->input_segment;

    GST_WARNING_OBJECT (decoder,
        "Received buffer without a new-segment. "
        "Assuming timestamps start from 0.");

    gst_segment_init (segment, GST_FORMAT_TIME);

    event = gst_event_new_segment (segment);

    decoder->priv->current_frame_events =
        g_list_prepend (decoder->priv->current_frame_events, event);
  }

  decoder->priv->had_input_data = TRUE;

  if (decoder->input_segment.rate > 0.0)
    ret = gst_video_decoder_chain_forward (decoder, buf, FALSE);
  else
    ret = gst_video_decoder_chain_reverse (decoder, buf);

  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
  return ret;

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

static GstStateChangeReturn
gst_video_decoder_change_state (GstElement * element, GstStateChange transition)
{
  GstVideoDecoder *decoder;
  GstVideoDecoderClass *decoder_class;
  GstStateChangeReturn ret;

  decoder = GST_VIDEO_DECODER (element);
  decoder_class = GST_VIDEO_DECODER_GET_CLASS (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      /* open device/library if needed */
      if (decoder_class->open && !decoder_class->open (decoder))
        goto open_failed;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      gst_video_decoder_reset (decoder, TRUE, TRUE);
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

      /* Initialize device/library if needed */
      if (decoder_class->start && !decoder_class->start (decoder))
        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 (decoder_class->stop)
        stopped = decoder_class->stop (decoder);

      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
      gst_video_decoder_reset (decoder, TRUE, TRUE);
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

      if (!stopped)
        goto stop_failed;

      break;
    }
    case GST_STATE_CHANGE_READY_TO_NULL:
      /* close device/library if needed */
      if (decoder_class->close && !decoder_class->close (decoder))
        goto close_failed;
      break;
    default:
      break;
  }

  return ret;

  /* Errors */
open_failed:
  {
    GST_ELEMENT_ERROR (decoder, LIBRARY, INIT, (NULL),
        ("Failed to open decoder"));
    return GST_STATE_CHANGE_FAILURE;
  }

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

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

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

static GstVideoCodecFrame *
gst_video_decoder_new_frame (GstVideoDecoder * decoder)
{
  GstVideoDecoderPrivate *priv = decoder->priv;
  GstVideoCodecFrame *frame;

  frame = g_slice_new0 (GstVideoCodecFrame);

  frame->ref_count = 1;

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);
  frame->system_frame_number = priv->system_frame_number;
  priv->system_frame_number++;
  frame->decode_frame_number = priv->decode_frame_number;
  priv->decode_frame_number++;

  frame->dts = GST_CLOCK_TIME_NONE;
  frame->pts = GST_CLOCK_TIME_NONE;
  frame->duration = GST_CLOCK_TIME_NONE;
  frame->events = priv->current_frame_events;
  priv->current_frame_events = NULL;

  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  GST_LOG_OBJECT (decoder, "Created new frame %p (sfn:%d)",
      frame, frame->system_frame_number);

  return frame;
}

static void
gst_video_decoder_push_event_list (GstVideoDecoder * decoder, GList * events)
{
  GList *l;

  /* events are stored in reverse order */
  for (l = g_list_last (events); l; l = g_list_previous (l)) {
    GST_LOG_OBJECT (decoder, "pushing %s event", GST_EVENT_TYPE_NAME (l->data));
    gst_video_decoder_push_event (decoder, l->data);
  }
  g_list_free (events);
}

static void
gst_video_decoder_prepare_finish_frame (GstVideoDecoder *
    decoder, GstVideoCodecFrame * frame, gboolean dropping)
{
  GstVideoDecoderPrivate *priv = decoder->priv;
  GList *l, *events = NULL;
  gboolean sync;

#ifndef GST_DISABLE_GST_DEBUG
  GST_LOG_OBJECT (decoder, "n %d in %" G_GSIZE_FORMAT " out %" G_GSIZE_FORMAT,
      g_list_length (priv->frames),
      gst_adapter_available (priv->input_adapter),
      gst_adapter_available (priv->output_adapter));
#endif

  sync = GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame);

  GST_LOG_OBJECT (decoder,
      "finish frame %p (#%d) sync:%d PTS:%" GST_TIME_FORMAT " DTS:%"
      GST_TIME_FORMAT,
      frame, frame->system_frame_number,
      sync, GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts));

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

    if (tmp->events) {
      events = g_list_concat (tmp->events, events);
      tmp->events = NULL;
    }

    if (tmp == frame)
      break;
  }

  if (dropping || !decoder->priv->output_state) {
    /* Push before the next frame that is not dropped */
    decoder->priv->pending_events =
        g_list_concat (events, decoder->priv->pending_events);
  } else {
    gst_video_decoder_push_event_list (decoder, decoder->priv->pending_events);
    decoder->priv->pending_events = NULL;

    gst_video_decoder_push_event_list (decoder, events);
  }

  /* Check if the data should not be displayed. For example altref/invisible
   * frame in vp8. In this case we should not update the timestamps. */
  if (GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (frame))
    return;

  /* If the frame is meant to be output but we don't have an output_buffer
   * we have a problem :) */
  if (G_UNLIKELY ((frame->output_buffer == NULL) && !dropping))
    goto no_output_buffer;

  if (GST_CLOCK_TIME_IS_VALID (frame->pts)) {
    if (frame->pts != priv->base_timestamp) {
      GST_DEBUG_OBJECT (decoder,
          "sync timestamp %" GST_TIME_FORMAT " diff %" GST_STIME_FORMAT,
          GST_TIME_ARGS (frame->pts),
          GST_STIME_ARGS (GST_CLOCK_DIFF (frame->pts,
                  decoder->output_segment.start)));
      priv->base_timestamp = frame->pts;
      priv->base_picture_number = frame->decode_frame_number;
    }
  }

  if (frame->duration == GST_CLOCK_TIME_NONE) {
    frame->duration = gst_video_decoder_get_frame_duration (decoder, frame);
    GST_LOG_OBJECT (decoder,
        "Guessing duration %" GST_TIME_FORMAT " for frame...",
        GST_TIME_ARGS (frame->duration));
  }

  /* PTS is expected montone ascending,
   * so a good guess is lowest unsent DTS */
  {
    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;
     * valid delta means we have reasonable DTS input */
    /* also, if we ended up reordered, means this approach is conflicting
     * with some sparse existing PTS, and so it does not work out */
    if (!priv->reordered_output &&
        !GST_CLOCK_TIME_IS_VALID (frame->pts) && !seen_none &&
        GST_CLOCK_TIME_IS_VALID (priv->pts_delta)) {
      frame->pts = min_ts + priv->pts_delta;
      GST_DEBUG_OBJECT (decoder,
          "no valid PTS, using oldest DTS %" GST_TIME_FORMAT,
          GST_TIME_ARGS (frame->pts));
    }

    /* some more maintenance, ts2 holds PTS */
    min_ts = GST_CLOCK_TIME_NONE;
    seen_none = FALSE;
    for (l = priv->frames; l; l = l->next) {
      GstVideoCodecFrame *tmp = l->data;

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

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

    /* if we detected reordered output, then PTS are void,
     * however those were obtained; bogus input, subclass etc */
    if (priv->reordered_output && !seen_none) {
      GST_DEBUG_OBJECT (decoder, "invalidating PTS");
      frame->pts = GST_CLOCK_TIME_NONE;
    }

    if (!GST_CLOCK_TIME_IS_VALID (frame->pts) && !seen_none) {
      frame->pts = min_ts;
      GST_DEBUG_OBJECT (decoder,
          "no valid PTS, using oldest PTS %" GST_TIME_FORMAT,
          GST_TIME_ARGS (frame->pts));
    }
  }


  if (frame->pts == GST_CLOCK_TIME_NONE) {
    /* Last ditch timestamp guess: Just add the duration to the previous
     * frame. If it's the first frame, just use the segment start. */
    if (frame->duration != GST_CLOCK_TIME_NONE) {
      if (GST_CLOCK_TIME_IS_VALID (priv->last_timestamp_out))
        frame->pts = priv->last_timestamp_out + frame->duration;
      else if (decoder->output_segment.rate > 0.0)
        frame->pts = decoder->output_segment.start;
      GST_LOG_OBJECT (decoder,
          "Guessing timestamp %" GST_TIME_FORMAT " for frame...",
          GST_TIME_ARGS (frame->pts));
    } else if (sync && frame->dts != GST_CLOCK_TIME_NONE) {
      frame->pts = frame->dts;
      GST_LOG_OBJECT (decoder,
          "Setting DTS as PTS %" GST_TIME_FORMAT " for frame...",
          GST_TIME_ARGS (frame->pts));
    }
  }

  if (GST_CLOCK_TIME_IS_VALID (priv->last_timestamp_out)) {
    if (frame->pts < priv->last_timestamp_out) {
      GST_WARNING_OBJECT (decoder,
          "decreasing timestamp (%" GST_TIME_FORMAT " < %"
          GST_TIME_FORMAT ")",
          GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (priv->last_timestamp_out));
      priv->reordered_output = TRUE;
      /* make it a bit less weird downstream */
      frame->pts = priv->last_timestamp_out;
    }
  }

  if (GST_CLOCK_TIME_IS_VALID (frame->pts))
    priv->last_timestamp_out = frame->pts;

  return;

  /* ERRORS */
no_output_buffer:
  {
    GST_ERROR_OBJECT (decoder, "No buffer to output !");
  }
}

/**
 * gst_video_decoder_release_frame:
 * @dec: a #GstVideoDecoder
 * @frame: (transfer full): the #GstVideoCodecFrame to release
 *
 * Similar to gst_video_decoder_drop_frame(), but simply releases @frame
 * without any processing other than removing it from list of pending frames,
 * after which it is considered finished and released.
 *
 * Since: 1.2.2
 */
void
gst_video_decoder_release_frame (GstVideoDecoder * dec,
    GstVideoCodecFrame * frame)
{
  GList *link;

  /* unref once from the list */
  GST_VIDEO_DECODER_STREAM_LOCK (dec);
  link = g_list_find (dec->priv->frames, frame);
  if (link) {
    gst_video_codec_frame_unref (frame);
    dec->priv->frames = g_list_delete_link (dec->priv->frames, link);
  }
  if (frame->events) {
    dec->priv->pending_events =
        g_list_concat (frame->events, dec->priv->pending_events);
    frame->events = NULL;
  }
  GST_VIDEO_DECODER_STREAM_UNLOCK (dec);

  /* unref because this function takes ownership */
  gst_video_codec_frame_unref (frame);
}

/**
 * gst_video_decoder_drop_frame:
 * @dec: a #GstVideoDecoder
 * @frame: (transfer full): the #GstVideoCodecFrame to drop
 *
 * Similar to gst_video_decoder_finish_frame(), but drops @frame in any
 * case and posts a QoS message with the frame's details on the bus.
 * In any case, the frame is considered finished and released.
 *
 * Returns: a #GstFlowReturn, usually GST_FLOW_OK.
 */
GstFlowReturn
gst_video_decoder_drop_frame (GstVideoDecoder * dec, GstVideoCodecFrame * frame)
{
  GstClockTime stream_time, jitter, earliest_time, qostime, timestamp;
  GstSegment *segment;
  GstMessage *qos_msg;
  gdouble proportion;

  GST_LOG_OBJECT (dec, "drop frame %p", frame);

  GST_VIDEO_DECODER_STREAM_LOCK (dec);

  gst_video_decoder_prepare_finish_frame (dec, frame, TRUE);

  GST_DEBUG_OBJECT (dec, "dropping frame %" GST_TIME_FORMAT,
      GST_TIME_ARGS (frame->pts));

  dec->priv->dropped++;

  /* post QoS message */
  GST_OBJECT_LOCK (dec);
  proportion = dec->priv->proportion;
  earliest_time = dec->priv->earliest_time;
  GST_OBJECT_UNLOCK (dec);

  timestamp = frame->pts;
  segment = &dec->output_segment;
  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
    segment = &dec->input_segment;
  stream_time =
      gst_segment_to_stream_time (segment, GST_FORMAT_TIME, timestamp);
  qostime = gst_segment_to_running_time (segment, GST_FORMAT_TIME, timestamp);
  jitter = GST_CLOCK_DIFF (qostime, earliest_time);
  qos_msg =
      gst_message_new_qos (GST_OBJECT_CAST (dec), FALSE, qostime, stream_time,
      timestamp, GST_CLOCK_TIME_NONE);
  gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
  gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
      dec->priv->processed, dec->priv->dropped);
  gst_element_post_message (GST_ELEMENT_CAST (dec), qos_msg);

  /* now free the frame */
  gst_video_decoder_release_frame (dec, frame);

  GST_VIDEO_DECODER_STREAM_UNLOCK (dec);

  return GST_FLOW_OK;
}

static gboolean
gst_video_decoder_transform_meta_default (GstVideoDecoder *
    decoder, 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
{
  GstVideoDecoder *decoder;
  GstVideoCodecFrame *frame;
} CopyMetaData;

static gboolean
foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
{
  CopyMetaData *data = user_data;
  GstVideoDecoder *decoder = data->decoder;
  GstVideoDecoderClass *klass = GST_VIDEO_DECODER_GET_CLASS (decoder);
  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 (decoder, "not copying memory specific metadata %s",
        g_type_name (info->api));
    do_copy = FALSE;
  } else if (klass->transform_meta) {
    do_copy = klass->transform_meta (decoder, frame, *meta);
    GST_DEBUG_OBJECT (decoder, "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 (decoder, "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_decoder_finish_frame:
 * @decoder: a #GstVideoDecoder
 * @frame: (transfer full): a decoded #GstVideoCodecFrame
 *
 * @frame should have a valid decoded data buffer, whose metadata fields
 * are then appropriately set according to frame data and pushed downstream.
 * If no output data is provided, @frame is considered skipped.
 * 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_decoder_finish_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);
  GstVideoDecoderPrivate *priv = decoder->priv;
  GstBuffer *output_buffer;
  gboolean needs_reconfigure = FALSE;

  GST_LOG_OBJECT (decoder, "finish frame %p", frame);

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);

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

  gst_video_decoder_prepare_finish_frame (decoder, frame, FALSE);
  priv->processed++;

  if (priv->tags_changed) {
    GstEvent *tags_event;

    tags_event = gst_video_decoder_create_merged_tags_event (decoder);

    if (tags_event != NULL)
      gst_video_decoder_push_event (decoder, tags_event);

    priv->tags_changed = FALSE;
  }

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

  /* We need a writable buffer for the metadata changes below */
  output_buffer = frame->output_buffer =
      gst_buffer_make_writable (frame->output_buffer);

  GST_BUFFER_FLAG_UNSET (output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);

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

  GST_BUFFER_OFFSET (output_buffer) = GST_BUFFER_OFFSET_NONE;
  GST_BUFFER_OFFSET_END (output_buffer) = GST_BUFFER_OFFSET_NONE;

  if (priv->discont) {
    GST_BUFFER_FLAG_SET (output_buffer, GST_BUFFER_FLAG_DISCONT);
  }

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

      data.decoder = decoder;
      data.frame = frame;
      gst_buffer_foreach_meta (frame->input_buffer, foreach_metadata, &data);
    } else {
      GST_WARNING_OBJECT (decoder,
          "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
   */
  output_buffer = gst_buffer_ref (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_decoder_release_frame (decoder, frame);
  frame = NULL;

  if (decoder->output_segment.rate < 0.0
      && !(decoder->output_segment.flags & GST_SEEK_FLAG_TRICKMODE_KEY_UNITS)) {
    GST_LOG_OBJECT (decoder, "queued frame");
    priv->output_queued = g_list_prepend (priv->output_queued, output_buffer);
  } else {
    ret = gst_video_decoder_clip_and_push_buf (decoder, output_buffer);
  }

done:
  if (frame)
    gst_video_decoder_release_frame (decoder, frame);
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
  return ret;
}

/* With stream lock, takes the frame reference */
static GstFlowReturn
gst_video_decoder_clip_and_push_buf (GstVideoDecoder * decoder, GstBuffer * buf)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstVideoDecoderPrivate *priv = decoder->priv;
  guint64 start, stop;
  guint64 cstart, cstop;
  GstSegment *segment;
  GstClockTime duration;

  /* Check for clipping */
  start = GST_BUFFER_PTS (buf);
  duration = GST_BUFFER_DURATION (buf);

  /* store that we have valid decoded data */
  priv->had_output_data = TRUE;

  stop = GST_CLOCK_TIME_NONE;

  if (GST_CLOCK_TIME_IS_VALID (start) && GST_CLOCK_TIME_IS_VALID (duration)) {
    stop = start + duration;
  } else if (GST_CLOCK_TIME_IS_VALID (start)
      && !GST_CLOCK_TIME_IS_VALID (duration)) {
    /* If we don't clip away buffers that far before the segment we
     * can cause the pipeline to lockup. This can happen if audio is
     * properly clipped, and thus the audio sink does not preroll yet
     * but the video sink prerolls because we already outputted a
     * buffer here... and then queues run full.
     *
     * In the worst case we will clip one buffer too many here now if no
     * framerate is given, no buffer duration is given and the actual
     * framerate is lower than 25fps */
    stop = start + 40 * GST_MSECOND;
  }

  segment = &decoder->output_segment;
  if (gst_segment_clip (segment, GST_FORMAT_TIME, start, stop, &cstart, &cstop)) {
    GST_BUFFER_PTS (buf) = cstart;

    if (stop != GST_CLOCK_TIME_NONE && GST_CLOCK_TIME_IS_VALID (duration))
      GST_BUFFER_DURATION (buf) = cstop - cstart;

    GST_LOG_OBJECT (decoder,
        "accepting buffer inside segment: %" GST_TIME_FORMAT " %"
        GST_TIME_FORMAT " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT
        " time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (cstart),
        GST_TIME_ARGS (cstop),
        GST_TIME_ARGS (segment->start), GST_TIME_ARGS (segment->stop),
        GST_TIME_ARGS (segment->time));
  } else {
    GST_LOG_OBJECT (decoder,
        "dropping buffer outside segment: %" GST_TIME_FORMAT
        " %" GST_TIME_FORMAT
        " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT
        " time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
        GST_TIME_ARGS (segment->start),
        GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time));
    /* only check and return EOS if upstream still
     * in the same segment and interested as such */
    if (decoder->priv->in_out_segment_sync) {
      if (segment->rate >= 0) {
        if (GST_BUFFER_PTS (buf) >= segment->stop)
          ret = GST_FLOW_EOS;
      } else if (GST_BUFFER_PTS (buf) < segment->start) {
        ret = GST_FLOW_EOS;
      }
    }
    gst_buffer_unref (buf);
    goto done;
  }

  /* Is buffer too late (QoS) ? */
  if (GST_CLOCK_TIME_IS_VALID (priv->earliest_time)
      && GST_CLOCK_TIME_IS_VALID (cstart)) {
    GstClockTime deadline =
        gst_segment_to_running_time (segment, GST_FORMAT_TIME, cstart);
    if (GST_CLOCK_TIME_IS_VALID (deadline) && deadline < priv->earliest_time) {
      GST_DEBUG_OBJECT (decoder,
          "Dropping frame due to QoS. start:%" GST_TIME_FORMAT " deadline:%"
          GST_TIME_FORMAT " earliest_time:%" GST_TIME_FORMAT,
          GST_TIME_ARGS (start), GST_TIME_ARGS (deadline),
          GST_TIME_ARGS (priv->earliest_time));
      gst_buffer_unref (buf);
      priv->discont = TRUE;
      goto done;
    }
  }

  /* Set DISCONT flag here ! */

  if (priv->discont) {
    GST_DEBUG_OBJECT (decoder, "Setting discont on output buffer");
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    priv->discont = FALSE;
  }

  /* update rate estimate */
  GST_OBJECT_LOCK (decoder);
  priv->bytes_out += gst_buffer_get_size (buf);
  if (GST_CLOCK_TIME_IS_VALID (duration)) {
    priv->time += duration;
  } else {
    /* FIXME : Use difference between current and previous outgoing
     * timestamp, and relate to difference between current and previous
     * bytes */
    /* better none than nothing valid */
    priv->time = GST_CLOCK_TIME_NONE;
  }
  GST_OBJECT_UNLOCK (decoder);

  GST_DEBUG_OBJECT (decoder, "pushing buffer %p of size %" G_GSIZE_FORMAT ", "
      "PTS %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
      gst_buffer_get_size (buf),
      GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));

  /* we got data, so note things are looking up again, reduce
   * the error count, if there is one */
  if (G_UNLIKELY (priv->error_count))
    priv->error_count = 0;

#ifndef GST_DISABLE_DEBUG
  if (G_UNLIKELY (priv->last_reset_time != GST_CLOCK_TIME_NONE)) {
    GstClockTime elapsed = gst_util_get_timestamp () - priv->last_reset_time;

    /* First buffer since reset, report how long we took */
    GST_INFO_OBJECT (decoder, "First buffer since flush took %" GST_TIME_FORMAT
        " to produce", GST_TIME_ARGS (elapsed));
    priv->last_reset_time = GST_CLOCK_TIME_NONE;
  }
#endif

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

done:
  return ret;
}

/**
 * gst_video_decoder_add_to_frame:
 * @decoder: a #GstVideoDecoder
 * @n_bytes: the number of bytes to add
 *
 * Removes next @n_bytes of input data and adds it to currently parsed frame.
 */
void
gst_video_decoder_add_to_frame (GstVideoDecoder * decoder, int n_bytes)
{
  GstVideoDecoderPrivate *priv = decoder->priv;
  GstBuffer *buf;

  GST_LOG_OBJECT (decoder, "add %d bytes to frame", n_bytes);

  if (n_bytes == 0)
    return;

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);
  if (gst_adapter_available (priv->output_adapter) == 0) {
    priv->frame_offset =
        priv->input_offset - gst_adapter_available (priv->input_adapter);
  }
  buf = gst_adapter_take_buffer (priv->input_adapter, n_bytes);

  gst_adapter_push (priv->output_adapter, buf);
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
}

/**
 * gst_video_decoder_get_pending_frame_size:
 * @decoder: a #GstVideoDecoder
 *
 * Returns the number of bytes previously added to the current frame
 * by calling gst_video_decoder_add_to_frame().
 *
 * Returns: The number of bytes pending for the current frame
 *
 * Since: 1.4
 */
gsize
gst_video_decoder_get_pending_frame_size (GstVideoDecoder * decoder)
{
  GstVideoDecoderPrivate *priv = decoder->priv;
  gsize ret;

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);
  ret = gst_adapter_available (priv->output_adapter);
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  GST_LOG_OBJECT (decoder, "Current pending frame has %" G_GSIZE_FORMAT "bytes",
      ret);

  return ret;
}

static guint64
gst_video_decoder_get_frame_duration (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame)
{
  GstVideoCodecState *state = decoder->priv->output_state;

  /* it's possible that we don't have a state yet when we are dropping the
   * initial buffers */
  if (state == NULL)
    return GST_CLOCK_TIME_NONE;

  if (state->info.fps_d == 0 || state->info.fps_n == 0) {
    return GST_CLOCK_TIME_NONE;
  }

  /* FIXME: For interlaced frames this needs to take into account
   * the number of valid fields in the frame
   */

  return gst_util_uint64_scale (GST_SECOND, state->info.fps_d,
      state->info.fps_n);
}

/**
 * gst_video_decoder_have_frame:
 * @decoder: a #GstVideoDecoder
 *
 * Gathers all data collected for currently parsed frame, gathers corresponding
 * metadata and passes it along for further processing, i.e. @handle_frame.
 *
 * Returns: a #GstFlowReturn
 */
GstFlowReturn
gst_video_decoder_have_frame (GstVideoDecoder * decoder)
{
  GstVideoDecoderPrivate *priv = decoder->priv;
  GstBuffer *buffer;
  int n_available;
  GstClockTime pts, dts, duration;
  guint flags;
  GstFlowReturn ret = GST_FLOW_OK;

  GST_LOG_OBJECT (decoder, "have_frame at offset %" G_GUINT64_FORMAT,
      priv->frame_offset);

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);

  n_available = gst_adapter_available (priv->output_adapter);
  if (n_available) {
    buffer = gst_adapter_take_buffer (priv->output_adapter, n_available);
  } else {
    buffer = gst_buffer_new_and_alloc (0);
  }

  priv->current_frame->input_buffer = buffer;

  gst_video_decoder_get_buffer_info_at_offset (decoder,
      priv->frame_offset, &pts, &dts, &duration, &flags);

  GST_BUFFER_PTS (buffer) = pts;
  GST_BUFFER_DTS (buffer) = dts;
  GST_BUFFER_DURATION (buffer) = duration;
  GST_BUFFER_FLAGS (buffer) = flags;

  GST_LOG_OBJECT (decoder, "collected frame size %d, "
      "PTS %" GST_TIME_FORMAT ", DTS %" GST_TIME_FORMAT ", dur %"
      GST_TIME_FORMAT, n_available, GST_TIME_ARGS (pts), GST_TIME_ARGS (dts),
      GST_TIME_ARGS (duration));

  if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
    GST_LOG_OBJECT (decoder, "Marking as sync point");
    GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (priv->current_frame);
  }

  /* In reverse playback, just capture and queue frames for later processing */
  if (decoder->input_segment.rate < 0.0) {
    priv->parse_gather =
        g_list_prepend (priv->parse_gather, priv->current_frame);
  } else {
    /* Otherwise, decode the frame, which gives away our ref */
    ret = gst_video_decoder_decode_frame (decoder, priv->current_frame);
  }
  /* Current frame is gone now, either way */
  priv->current_frame = NULL;

  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return ret;
}

/* Pass the frame in priv->current_frame through the
 * handle_frame() callback for decoding and passing to gvd_finish_frame(),
 * or dropping by passing to gvd_drop_frame() */
static GstFlowReturn
gst_video_decoder_decode_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame)
{
  GstVideoDecoderPrivate *priv = decoder->priv;
  GstVideoDecoderClass *decoder_class;
  GstFlowReturn ret = GST_FLOW_OK;

  decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);

  /* FIXME : This should only have to be checked once (either the subclass has an
   * implementation, or it doesn't) */
  g_return_val_if_fail (decoder_class->handle_frame != NULL, GST_FLOW_ERROR);

  frame->distance_from_sync = priv->distance_from_sync;
  priv->distance_from_sync++;
  frame->pts = GST_BUFFER_PTS (frame->input_buffer);
  frame->dts = GST_BUFFER_DTS (frame->input_buffer);
  frame->duration = GST_BUFFER_DURATION (frame->input_buffer);

  /* For keyframes, PTS = DTS + constant_offset, usually 0 to 3 frame
   * durations. */
  /* FIXME upstream can be quite wrong about the keyframe aspect,
   * so we could be going off here as well,
   * maybe let subclass decide if it really is/was a keyframe */
  if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) &&
      GST_CLOCK_TIME_IS_VALID (frame->pts)
      && GST_CLOCK_TIME_IS_VALID (frame->dts)) {
    /* just in case they are not equal as might ideally be,
     * e.g. quicktime has a (positive) delta approach */
    priv->pts_delta = frame->pts - frame->dts;
    GST_DEBUG_OBJECT (decoder, "PTS delta %d ms",
        (gint) (priv->pts_delta / GST_MSECOND));
  }

  frame->abidata.ABI.ts = frame->dts;
  frame->abidata.ABI.ts2 = frame->pts;

  GST_LOG_OBJECT (decoder, "PTS %" GST_TIME_FORMAT ", DTS %" GST_TIME_FORMAT
      ", dist %d", GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts),
      frame->distance_from_sync);

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

  if (g_list_length (priv->frames) > 10) {
    GST_DEBUG_OBJECT (decoder, "decoder frame list getting long: %d frames,"
        "possible internal leaking?", g_list_length (priv->frames));
  }

  frame->deadline =
      gst_segment_to_running_time (&decoder->input_segment, GST_FORMAT_TIME,
      frame->pts);

  /* do something with frame */
  ret = decoder_class->handle_frame (decoder, frame);
  if (ret != GST_FLOW_OK)
    GST_DEBUG_OBJECT (decoder, "flow error %s", gst_flow_get_name (ret));

  /* the frame has either been added to parse_gather or sent to
     handle frame so there is no need to unref it */
  return ret;
}


/**
 * gst_video_decoder_get_output_state:
 * @decoder: a #GstVideoDecoder
 *
 * Get the #GstVideoCodecState currently describing the output stream.
 *
 * Returns: (transfer full): #GstVideoCodecState describing format of video data.
 */
GstVideoCodecState *
gst_video_decoder_get_output_state (GstVideoDecoder * decoder)
{
  GstVideoCodecState *state = NULL;

  GST_OBJECT_LOCK (decoder);
  if (decoder->priv->output_state)
    state = gst_video_codec_state_ref (decoder->priv->output_state);
  GST_OBJECT_UNLOCK (decoder);

  return state;
}

/**
 * gst_video_decoder_set_output_state:
 * @decoder: a #GstVideoDecoder
 * @fmt: a #GstVideoFormat
 * @width: The width in pixels
 * @height: The height in pixels
 * @reference: (allow-none) (transfer none): An optional reference #GstVideoCodecState
 *
 * Creates a new #GstVideoCodecState with the specified @fmt, @width and @height
 * as the output state for the decoder.
 * Any previously set output state on @decoder will be replaced by the newly
 * created one.
 *
 * If the subclass wishes to copy over existing fields (like pixel aspec 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_decoder_finish_frame().
 *
 * Returns: (transfer full): the newly configured output state.
 */
GstVideoCodecState *
gst_video_decoder_set_output_state (GstVideoDecoder * decoder,
    GstVideoFormat fmt, guint width, guint height,
    GstVideoCodecState * reference)
{
  GstVideoDecoderPrivate *priv = decoder->priv;
  GstVideoCodecState *state;

  GST_DEBUG_OBJECT (decoder, "fmt:%d, width:%d, height:%d, reference:%p",
      fmt, width, height, reference);

  /* Create the new output state */
  state = _new_output_state (fmt, width, height, reference);
  if (!state)
    return NULL;

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);

  GST_OBJECT_LOCK (decoder);
  /* Replace existing output state by new one */
  if (priv->output_state)
    gst_video_codec_state_unref (priv->output_state);
  priv->output_state = gst_video_codec_state_ref (state);

  if (priv->output_state != NULL && priv->output_state->info.fps_n > 0) {
    priv->qos_frame_duration =
        gst_util_uint64_scale (GST_SECOND, priv->output_state->info.fps_d,
        priv->output_state->info.fps_n);
  } else {
    priv->qos_frame_duration = 0;
  }
  priv->output_state_changed = TRUE;
  GST_OBJECT_UNLOCK (decoder);

  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return state;
}


/**
 * gst_video_decoder_get_oldest_frame:
 * @decoder: a #GstVideoDecoder
 *
 * Get the oldest pending unfinished #GstVideoCodecFrame
 *
 * Returns: (transfer full): oldest pending unfinished #GstVideoCodecFrame.
 */
GstVideoCodecFrame *
gst_video_decoder_get_oldest_frame (GstVideoDecoder * decoder)
{
  GstVideoCodecFrame *frame = NULL;

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);
  if (decoder->priv->frames)
    frame = gst_video_codec_frame_ref (decoder->priv->frames->data);
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return (GstVideoCodecFrame *) frame;
}

/**
 * gst_video_decoder_get_frame:
 * @decoder: a #GstVideoDecoder
 * @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_decoder_get_frame (GstVideoDecoder * decoder, int frame_number)
{
  GList *g;
  GstVideoCodecFrame *frame = NULL;

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

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);
  for (g = decoder->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_DECODER_STREAM_UNLOCK (decoder);

  return frame;
}

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

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);
  frames = g_list_copy (decoder->priv->frames);
  g_list_foreach (frames, (GFunc) gst_video_codec_frame_ref, NULL);
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return frames;
}

static gboolean
gst_video_decoder_decide_allocation_default (GstVideoDecoder * decoder,
    GstQuery * query)
{
  GstCaps *outcaps = NULL;
  GstBufferPool *pool = NULL;
  guint size, min, max;
  GstAllocator *allocator = NULL;
  GstAllocationParams params;
  GstStructure *config;
  gboolean update_pool, update_allocator;
  GstVideoInfo vinfo;

  gst_query_parse_allocation (query, &outcaps, NULL);
  gst_video_info_init (&vinfo);
  if (outcaps)
    gst_video_info_from_caps (&vinfo, outcaps);

  /* 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 (gst_query_get_n_allocation_pools (query) > 0) {
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
    size = MAX (size, vinfo.size);
    update_pool = TRUE;
  } else {
    pool = NULL;
    size = vinfo.size;
    min = max = 0;

    update_pool = FALSE;
  }

  if (pool == NULL) {
    /* no pool, we can make our own */
    GST_DEBUG_OBJECT (decoder, "no pool, making new pool");
    pool = gst_video_buffer_pool_new ();
  }

  /* now configure */
  config = gst_buffer_pool_get_config (pool);
  gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
  gst_buffer_pool_config_set_allocator (config, allocator, &params);

  GST_DEBUG_OBJECT (decoder,
      "setting config %" GST_PTR_FORMAT " in pool %" GST_PTR_FORMAT, config,
      pool);
  if (!gst_buffer_pool_set_config (pool, config)) {
    config = gst_buffer_pool_get_config (pool);

    /* If change are not acceptable, fallback to generic pool */
    if (!gst_buffer_pool_config_validate_params (config, outcaps, size, min,
            max)) {
      GST_DEBUG_OBJECT (decoder, "unsuported pool, making new pool");

      gst_object_unref (pool);
      pool = gst_video_buffer_pool_new ();
      gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
      gst_buffer_pool_config_set_allocator (config, allocator, &params);
    }

    if (!gst_buffer_pool_set_config (pool, config))
      goto config_failed;
  }

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

  if (update_pool)
    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
  else
    gst_query_add_allocation_pool (query, pool, size, min, max);

  if (pool)
    gst_object_unref (pool);

  return TRUE;

config_failed:
  if (allocator)
    gst_object_unref (allocator);
  if (pool)
    gst_object_unref (pool);
  GST_ELEMENT_ERROR (decoder, RESOURCE, SETTINGS,
      ("Failed to configure the buffer pool"),
      ("Configuration is most likely invalid, please report this issue."));
  return FALSE;
}

static gboolean
gst_video_decoder_propose_allocation_default (GstVideoDecoder * decoder,
    GstQuery * query)
{
  return TRUE;
}

static gboolean
gst_video_decoder_negotiate_pool (GstVideoDecoder * decoder, GstCaps * caps)
{
  GstVideoDecoderClass *klass;
  GstQuery *query = NULL;
  GstBufferPool *pool = NULL;
  GstAllocator *allocator;
  GstAllocationParams params;
  gboolean ret = TRUE;

  klass = GST_VIDEO_DECODER_GET_CLASS (decoder);

  query = gst_query_new_allocation (caps, TRUE);

  GST_DEBUG_OBJECT (decoder, "do query ALLOCATION");

  if (!gst_pad_peer_query (decoder->srcpad, query)) {
    GST_DEBUG_OBJECT (decoder, "didn't get downstream ALLOCATION hints");
  }

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

  GST_DEBUG_OBJECT (decoder, "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 (gst_query_get_n_allocation_pools (query) > 0)
    gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
  if (!pool) {
    if (allocator)
      gst_object_unref (allocator);
    ret = FALSE;
    goto no_decide_allocation;
  }

  if (decoder->priv->allocator)
    gst_object_unref (decoder->priv->allocator);
  decoder->priv->allocator = allocator;
  decoder->priv->params = params;

  if (decoder->priv->pool) {
    /* do not set the bufferpool to inactive here, it will be done
     * on its finalize function. As videodecoder do late renegotiation
     * it might happen that some element downstream is already using this
     * same bufferpool and deactivating it will make it fail.
     * Happens when a downstream element changes from passthrough to
     * non-passthrough and gets this same bufferpool to use */
    GST_DEBUG_OBJECT (decoder, "unref pool %" GST_PTR_FORMAT,
        decoder->priv->pool);
    gst_object_unref (decoder->priv->pool);
  }
  decoder->priv->pool = pool;

  /* and activate */
  GST_DEBUG_OBJECT (decoder, "activate pool %" GST_PTR_FORMAT, pool);
  gst_buffer_pool_set_active (pool, TRUE);

done:
  if (query)
    gst_query_unref (query);

  return ret;

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

static gboolean
gst_video_decoder_negotiate_default (GstVideoDecoder * decoder)
{
  GstVideoCodecState *state = decoder->priv->output_state;
  gboolean ret = TRUE;
  GstVideoCodecFrame *frame;
  GstCaps *prevcaps;

  if (!state) {
    GST_DEBUG_OBJECT (decoder,
        "Trying to negotiate the pool with out setting the o/p format");
    ret = gst_video_decoder_negotiate_pool (decoder, NULL);
    goto done;
  }

  g_return_val_if_fail (GST_VIDEO_INFO_WIDTH (&state->info) != 0, FALSE);
  g_return_val_if_fail (GST_VIDEO_INFO_HEIGHT (&state->info) != 0, FALSE);

  /* If the base class didn't set any multiview params, assume mono
   * now */
  if (GST_VIDEO_INFO_MULTIVIEW_MODE (&state->info) ==
      GST_VIDEO_MULTIVIEW_MODE_NONE) {
    GST_VIDEO_INFO_MULTIVIEW_MODE (&state->info) =
        GST_VIDEO_MULTIVIEW_MODE_MONO;
    GST_VIDEO_INFO_MULTIVIEW_FLAGS (&state->info) =
        GST_VIDEO_MULTIVIEW_FLAGS_NONE;
  }

  GST_DEBUG_OBJECT (decoder, "output_state par %d/%d fps %d/%d",
      state->info.par_n, state->info.par_d,
      state->info.fps_n, state->info.fps_d);

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

  GST_DEBUG_OBJECT (decoder, "setting caps %" GST_PTR_FORMAT, state->caps);

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

    if (frame) {
      events = &frame->events;
    } else {
      events = &decoder->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_decoder_push_event (decoder, event);
        tmp = l;
        l = l->prev;
        *events = g_list_delete_link (*events, tmp);
      } else {
        l = l->prev;
      }
    }
  }

  prevcaps = gst_pad_get_current_caps (decoder->srcpad);
  if (!prevcaps || !gst_caps_is_equal (prevcaps, state->caps)) {
    if (!prevcaps) {
      GST_DEBUG_OBJECT (decoder, "decoder src pad has currently NULL caps");
    }
    ret = gst_pad_set_caps (decoder->srcpad, state->caps);
  } else {
    ret = TRUE;
    GST_DEBUG_OBJECT (decoder,
        "current src pad and output state caps are the same");
  }
  if (prevcaps)
    gst_caps_unref (prevcaps);

  if (!ret)
    goto done;
  decoder->priv->output_state_changed = FALSE;
  /* Negotiate pool */
  ret = gst_video_decoder_negotiate_pool (decoder, state->allocation_caps);

done:
  return ret;
}

static gboolean
gst_video_decoder_negotiate_unlocked (GstVideoDecoder * decoder)
{
  GstVideoDecoderClass *klass = GST_VIDEO_DECODER_GET_CLASS (decoder);
  gboolean ret = TRUE;

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

  return ret;
}

/**
 * gst_video_decoder_negotiate:
 * @decoder: a #GstVideoDecoder
 *
 * 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_decoder_negotiate (GstVideoDecoder * decoder)
{
  GstVideoDecoderClass *klass;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_VIDEO_DECODER (decoder), FALSE);

  klass = GST_VIDEO_DECODER_GET_CLASS (decoder);

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);
  gst_pad_check_reconfigure (decoder->srcpad);
  if (klass->negotiate) {
    ret = klass->negotiate (decoder);
    if (!ret)
      gst_pad_mark_reconfigure (decoder->srcpad);
  }
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return ret;
}

/**
 * gst_video_decoder_allocate_output_buffer:
 * @decoder: a #GstVideoDecoder
 *
 * Helper function that allocates a buffer to hold a video frame for @decoder's
 * current #GstVideoCodecState.
 *
 * You should use gst_video_decoder_allocate_output_frame() instead of this
 * function, if possible at all.
 *
 * Returns: (transfer full): allocated buffer, or NULL if no buffer could be
 *     allocated (e.g. when downstream is flushing or shutting down)
 */
GstBuffer *
gst_video_decoder_allocate_output_buffer (GstVideoDecoder * decoder)
{
  GstFlowReturn flow;
  GstBuffer *buffer = NULL;
  gboolean needs_reconfigure = FALSE;

  GST_DEBUG ("alloc src buffer");

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);
  needs_reconfigure = gst_pad_check_reconfigure (decoder->srcpad);
  if (G_UNLIKELY (!decoder->priv->output_state
          || decoder->priv->output_state_changed || needs_reconfigure)) {
    if (!gst_video_decoder_negotiate_unlocked (decoder)) {
      if (decoder->priv->output_state) {
        GST_DEBUG_OBJECT (decoder, "Failed to negotiate, fallback allocation");
        gst_pad_mark_reconfigure (decoder->srcpad);
        goto fallback;
      } else {
        GST_DEBUG_OBJECT (decoder, "Failed to negotiate, output_buffer=NULL");
        goto failed_allocation;
      }
    }
  }

  flow = gst_buffer_pool_acquire_buffer (decoder->priv->pool, &buffer, NULL);

  if (flow != GST_FLOW_OK) {
    GST_INFO_OBJECT (decoder, "couldn't allocate output buffer, flow %s",
        gst_flow_get_name (flow));
    if (decoder->priv->output_state && decoder->priv->output_state->info.size)
      goto fallback;
    else
      goto failed_allocation;
  }
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return buffer;

fallback:
  GST_INFO_OBJECT (decoder,
      "Fallback allocation, creating new buffer which doesn't belongs to any buffer pool");
  buffer =
      gst_buffer_new_allocate (NULL, decoder->priv->output_state->info.size,
      NULL);

failed_allocation:
  GST_ERROR_OBJECT (decoder, "Failed to allocate the buffer..");
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return buffer;
}

/**
 * gst_video_decoder_allocate_output_frame:
 * @decoder: a #GstVideoDecoder
 * @frame: a #GstVideoCodecFrame
 *
 * Helper function that allocates a buffer to hold a video frame for @decoder'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_decoder_allocate_output_frame (GstVideoDecoder *
    decoder, GstVideoCodecFrame * frame)
{
  return gst_video_decoder_allocate_output_frame_with_params (decoder, frame,
      NULL);
}

/**
 * gst_video_decoder_allocate_output_frame_with_params:
 * @decoder: a #GstVideoDecoder
 * @frame: a #GstVideoCodecFrame
 * @params: a #GstBufferPoolAcquireParams
 *
 * Same as #gst_video_decoder_allocate_output_frame except it allows passing
 * #GstBufferPoolAcquireParams to the sub call gst_buffer_pool_acquire_buffer.
 *
 * Returns: %GST_FLOW_OK if an output buffer could be allocated
 *
 * Since: 1.12
 */
GstFlowReturn
gst_video_decoder_allocate_output_frame_with_params (GstVideoDecoder *
    decoder, GstVideoCodecFrame * frame, GstBufferPoolAcquireParams * params)
{
  GstFlowReturn flow_ret;
  GstVideoCodecState *state;
  int num_bytes;
  gboolean needs_reconfigure = FALSE;

  g_return_val_if_fail (decoder->priv->output_state, GST_FLOW_NOT_NEGOTIATED);
  g_return_val_if_fail (frame->output_buffer == NULL, GST_FLOW_ERROR);

  GST_VIDEO_DECODER_STREAM_LOCK (decoder);

  state = decoder->priv->output_state;
  if (state == NULL) {
    g_warning ("Output state should be set before allocating frame");
    goto error;
  }
  num_bytes = GST_VIDEO_INFO_SIZE (&state->info);
  if (num_bytes == 0) {
    g_warning ("Frame size should not be 0");
    goto error;
  }

  needs_reconfigure = gst_pad_check_reconfigure (decoder->srcpad);
  if (G_UNLIKELY (decoder->priv->output_state_changed || needs_reconfigure)) {
    if (!gst_video_decoder_negotiate_unlocked (decoder)) {
      GST_DEBUG_OBJECT (decoder, "Failed to negotiate, fallback allocation");
      gst_pad_mark_reconfigure (decoder->srcpad);
    }
  }

  GST_LOG_OBJECT (decoder, "alloc buffer size %d", num_bytes);

  flow_ret = gst_buffer_pool_acquire_buffer (decoder->priv->pool,
      &frame->output_buffer, params);

  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

  return flow_ret;

error:
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
  return GST_FLOW_ERROR;
}

/**
 * gst_video_decoder_get_max_decode_time:
 * @decoder: a #GstVideoDecoder
 * @frame: a #GstVideoCodecFrame
 *
 * Determines maximum possible decoding time for @frame that will
 * allow it to decode and arrive in time (as determined by QoS events).
 * In particular, a negative result means decoding in time is no longer possible
 * and should therefore occur as soon/skippy as possible.
 *
 * Returns: max decoding time.
 */
GstClockTimeDiff
gst_video_decoder_get_max_decode_time (GstVideoDecoder *
    decoder, GstVideoCodecFrame * frame)
{
  GstClockTimeDiff deadline;
  GstClockTime earliest_time;

  GST_OBJECT_LOCK (decoder);
  earliest_time = decoder->priv->earliest_time;
  if (GST_CLOCK_TIME_IS_VALID (earliest_time)
      && GST_CLOCK_TIME_IS_VALID (frame->deadline))
    deadline = GST_CLOCK_DIFF (earliest_time, frame->deadline);
  else
    deadline = G_MAXINT64;

  GST_LOG_OBJECT (decoder, "earliest %" GST_TIME_FORMAT
      ", frame deadline %" GST_TIME_FORMAT ", deadline %" GST_STIME_FORMAT,
      GST_TIME_ARGS (earliest_time), GST_TIME_ARGS (frame->deadline),
      GST_STIME_ARGS (deadline));

  GST_OBJECT_UNLOCK (decoder);

  return deadline;
}

/**
 * gst_video_decoder_get_qos_proportion:
 * @decoder: a #GstVideoDecoder
 *     current QoS proportion, or %NULL
 *
 * Returns: The current QoS proportion.
 *
 * Since: 1.0.3
 */
gdouble
gst_video_decoder_get_qos_proportion (GstVideoDecoder * decoder)
{
  gdouble proportion;

  g_return_val_if_fail (GST_IS_VIDEO_DECODER (decoder), 1.0);

  GST_OBJECT_LOCK (decoder);
  proportion = decoder->priv->proportion;
  GST_OBJECT_UNLOCK (decoder);

  return proportion;
}

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

/**
 * gst_video_decoder_set_max_errors:
 * @dec: a #GstVideoDecoder
 * @num: max tolerated errors
 *
 * Sets numbers of tolerated decoder errors, where a tolerated one is then only
 * warned about, but more than tolerated will lead to fatal error.  You can set
 * -1 for never returning fatal errors. Default is set to
 * GST_VIDEO_DECODER_MAX_ERRORS.
 *
 * The '-1' option was added in 1.4
 */
void
gst_video_decoder_set_max_errors (GstVideoDecoder * dec, gint num)
{
  g_return_if_fail (GST_IS_VIDEO_DECODER (dec));

  dec->priv->max_errors = num;
}

/**
 * gst_video_decoder_get_max_errors:
 * @dec: a #GstVideoDecoder
 *
 * Returns: currently configured decoder tolerated error count.
 */
gint
gst_video_decoder_get_max_errors (GstVideoDecoder * dec)
{
  g_return_val_if_fail (GST_IS_VIDEO_DECODER (dec), 0);

  return dec->priv->max_errors;
}

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

  dec->priv->needs_format = enabled;
}

/**
 * gst_video_decoder_get_needs_format:
 * @dec: a #GstVideoDecoder
 *
 * Queries decoder required format handling.
 *
 * Returns: %TRUE if required format handling is enabled.
 *
 * Since: 1.4
 */
gboolean
gst_video_decoder_get_needs_format (GstVideoDecoder * dec)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_VIDEO_DECODER (dec), FALSE);

  result = dec->priv->needs_format;

  return result;
}

/**
 * gst_video_decoder_set_packetized:
 * @decoder: a #GstVideoDecoder
 * @packetized: whether the input data should be considered as packetized.
 *
 * Allows baseclass to consider input data as packetized or not. If the
 * input is packetized, then the @parse method will not be called.
 */
void
gst_video_decoder_set_packetized (GstVideoDecoder * decoder,
    gboolean packetized)
{
  decoder->priv->packetized = packetized;
}

/**
 * gst_video_decoder_get_packetized:
 * @decoder: a #GstVideoDecoder
 *
 * Queries whether input data is considered packetized or not by the
 * base class.
 *
 * Returns: TRUE if input data is considered packetized.
 */
gboolean
gst_video_decoder_get_packetized (GstVideoDecoder * decoder)
{
  return decoder->priv->packetized;
}

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

  dec->priv->do_estimate_rate = enabled;
}

/**
 * gst_video_decoder_get_estimate_rate:
 * @dec: a #GstVideoDecoder
 *
 * Returns: currently configured byte to time conversion setting
 */
gboolean
gst_video_decoder_get_estimate_rate (GstVideoDecoder * dec)
{
  g_return_val_if_fail (GST_IS_VIDEO_DECODER (dec), 0);

  return dec->priv->do_estimate_rate;
}

/**
 * gst_video_decoder_set_latency:
 * @decoder: a #GstVideoDecoder
 * @min_latency: minimum latency
 * @max_latency: maximum latency
 *
 * Lets #GstVideoDecoder sub-classes tell the baseclass what the decoder
 * latency is. Will also post a LATENCY message on the bus so the pipeline
 * can reconfigure its global latency.
 */
void
gst_video_decoder_set_latency (GstVideoDecoder * decoder,
    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 (decoder);
  decoder->priv->min_latency = min_latency;
  decoder->priv->max_latency = max_latency;
  GST_OBJECT_UNLOCK (decoder);

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

/**
 * gst_video_decoder_get_latency:
 * @decoder: a #GstVideoDecoder
 * @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 mximum latency, or %NULL
 *
 * Query the configured decoder latency. Results will be returned via
 * @min_latency and @max_latency.
 */
void
gst_video_decoder_get_latency (GstVideoDecoder * decoder,
    GstClockTime * min_latency, GstClockTime * max_latency)
{
  GST_OBJECT_LOCK (decoder);
  if (min_latency)
    *min_latency = decoder->priv->min_latency;
  if (max_latency)
    *max_latency = decoder->priv->max_latency;
  GST_OBJECT_UNLOCK (decoder);
}

/**
 * gst_video_decoder_merge_tags:
 * @decoder: a #GstVideoDecoder
 * @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 decoder tags and how they should be merged with any
 * upstream stream tags. This will override any tags previously-set
 * with gst_audio_decoder_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_decoder_merge_tags (GstVideoDecoder * decoder,
    const GstTagList * tags, GstTagMergeMode mode)
{
  g_return_if_fail (GST_IS_VIDEO_DECODER (decoder));
  g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));
  g_return_if_fail (tags == NULL || mode != GST_TAG_MERGE_UNDEFINED);

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

    GST_DEBUG_OBJECT (decoder, "set decoder tags to %" GST_PTR_FORMAT, tags);
    decoder->priv->tags_changed = TRUE;
  }
  GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
}

/**
 * gst_video_decoder_get_buffer_pool:
 * @decoder: a #GstVideoDecoder
 *
 * Returns: (transfer full): the instance of the #GstBufferPool used
 * by the decoder; free it after use it
 */
GstBufferPool *
gst_video_decoder_get_buffer_pool (GstVideoDecoder * decoder)
{
  g_return_val_if_fail (GST_IS_VIDEO_DECODER (decoder), NULL);

  if (decoder->priv->pool)
    return gst_object_ref (decoder->priv->pool);

  return NULL;
}

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

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

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

/**
 * gst_video_decoder_set_use_default_pad_acceptcaps:
 * @decoder: a #GstVideoDecoder
 * @use: if the default pad accept-caps query handling should be used
 *
 * Lets #GstVideoDecoder sub-classes decide if they want the sink pad
 * to use the default pad query handler to reply to accept-caps queries.
 *
 * By setting this to true it is possible to further customize the default
 * handler with %GST_PAD_SET_ACCEPT_INTERSECT and
 * %GST_PAD_SET_ACCEPT_TEMPLATE
 *
 * Since: 1.6
 */
void
gst_video_decoder_set_use_default_pad_acceptcaps (GstVideoDecoder * decoder,
    gboolean use)
{
  decoder->priv->use_default_pad_acceptcaps = use;
}
