/*
 * GStreamer
 * Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
 * Copyright (C) 2008-2010 Sebastian Dröge <slomo@collabora.co.uk>
 * Copyright (C) 2011 Robert Swain <robert.swain@collabora.co.uk>
 *
 * 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:element-deinterlace
 *
 * deinterlace deinterlaces interlaced video frames to progressive video frames.
 * For this different algorithms can be selected which will be described later.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v filesrc location=/path/to/file ! decodebin ! videoconvert ! deinterlace ! videoconvert ! autovideosink
 * ]| This pipeline deinterlaces a video file with the default deinterlacing options.
 * </refsect2>
 */

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

#include "gstdeinterlace.h"
#include "tvtime/plugins.h"

#include <string.h>

#if HAVE_ORC
#include <orc/orc.h>
#endif

GST_DEBUG_CATEGORY_STATIC (deinterlace_debug);
#define GST_CAT_DEFAULT (deinterlace_debug)

/* Properties */

#define DEFAULT_MODE            GST_DEINTERLACE_MODE_AUTO
#define DEFAULT_METHOD          GST_DEINTERLACE_LINEAR
#define DEFAULT_FIELDS          GST_DEINTERLACE_ALL
#define DEFAULT_FIELD_LAYOUT    GST_DEINTERLACE_LAYOUT_AUTO
#define DEFAULT_LOCKING         GST_DEINTERLACE_LOCKING_NONE
#define DEFAULT_IGNORE_OBSCURE  TRUE
#define DEFAULT_DROP_ORPHANS    TRUE

enum
{
  PROP_0,
  PROP_MODE,
  PROP_METHOD,
  PROP_FIELDS,
  PROP_FIELD_LAYOUT,
  PROP_LOCKING,
  PROP_IGNORE_OBSCURE,
  PROP_DROP_ORPHANS
};

#define GST_DEINTERLACE_BUFFER_STATE_P    (1<<0)
#define GST_DEINTERLACE_BUFFER_STATE_I    (1<<1)
#define GST_DEINTERLACE_BUFFER_STATE_TC_B (1<<2)
#define GST_DEINTERLACE_BUFFER_STATE_TC_T (1<<3)
#define GST_DEINTERLACE_BUFFER_STATE_TC_P (1<<4)
#define GST_DEINTERLACE_BUFFER_STATE_TC_M (1<<5)
#define GST_DEINTERLACE_BUFFER_STATE_RFF  (1<<6)

#define GST_ONE \
  (GST_DEINTERLACE_BUFFER_STATE_TC_T | GST_DEINTERLACE_BUFFER_STATE_TC_B)
#define GST_PRG \
  (GST_DEINTERLACE_BUFFER_STATE_P | GST_DEINTERLACE_BUFFER_STATE_TC_P)
#define GST_INT \
  (GST_DEINTERLACE_BUFFER_STATE_I | GST_DEINTERLACE_BUFFER_STATE_TC_M)
#define GST_RFF (GST_DEINTERLACE_BUFFER_STATE_RFF)

#define GST_DEINTERLACE_OBSCURE_THRESHOLD 5

static const TelecinePattern telecine_patterns[] = {
  /* 60i -> 60p or 50i -> 50p (NOTE THE WEIRD RATIOS) */
  {"1:1", 1, 2, 1, {GST_ONE,}},
  /* 60i -> 30p or 50i -> 25p */
  {"2:2", 1, 1, 1, {GST_INT,}},
  /* 60i telecine -> 24p */
  {"2:3-RFF", 4, 4, 5, {GST_PRG, GST_RFF, GST_PRG, GST_RFF,}},
  {"2:3", 5, 4, 5, {GST_PRG, GST_PRG, GST_ONE, GST_ONE, GST_PRG,}},
  {"3:2:2:3-RFF", 4, 4, 5, {GST_RFF, GST_PRG, GST_PRG, GST_RFF,}},
  {"3:2:2:3", 5, 4, 5, {GST_PRG, GST_ONE, GST_INT, GST_ONE, GST_PRG,}},
  /* fieldanalysis should indicate this using RFF on the second and fourth
   * buffers and not send the third buffer at all. it will be identified as
   * 3:2:2:3-RFF */
  /* {"2:3:3:2", 5, 4, 5, {GST_PRG, GST_PRG, GST_DRP, GST_PRG, GST_PRG,}}, */

  /* The following patterns are obscure and are ignored if ignore-obscure is
   * set to true. If any patterns are added above this line, check and edit
   * GST_DEINTERLACE_OBSCURE_THRESHOLD */

  /* 50i Euro pulldown -> 24p */
  {"2-11:3", 25, 24, 25, {GST_PRG, GST_PRG, GST_PRG, GST_PRG, GST_PRG,
              GST_PRG, GST_PRG, GST_PRG, GST_PRG, GST_PRG,
              GST_PRG, GST_PRG, GST_ONE, GST_INT, GST_INT,
              GST_INT, GST_INT, GST_INT, GST_INT, GST_INT,
          GST_INT, GST_INT, GST_INT, GST_ONE, GST_PRG,}},
#if 0
  /* haven't figured out how fieldanalysis should handle these yet */
  /* 60i (NTSC 30000/1001) -> 16p (16000/1001) */
  {"3:4-3", 15, 8, 15, {GST_PRG, GST_DRP, GST_PRG, GST_DRP, GST_PRG,
              GST_DRP, GST_PRG, GST_DRP, GST_PRG, GST_DRP,
          GST_PRG, GST_DRP, GST_PRG, GST_DRP, GST_PRG,}},
  /* 50i (PAL) -> 16p */
  {"3-7:4", 25, 16, 25, {GST_PRG, GST_DRP, GST_PRG, GST_PRG, GST_DRP,
              GST_PRG, GST_PRG, GST_DRP, GST_PRG, GST_PRG,
              GST_DRP, GST_PRG, GST_DRP, GST_PRG, GST_PRG,
              GST_DRP, GST_PRG, GST_PRG, GST_DRP, GST_PRG,
          GST_PRG, GST_DRP, GST_PRG, GST_PRG, GST_DRP,}},
  /* NTSC 60i -> 18p */
  {"3:3:4", 5, 3, 5, {GST_PRG, GST_DRP, GST_PRG, GST_DRP, GST_PRG,}},
  /* NTSC 60i -> 20p */
  {"3:3", 3, 2, 3, {GST_PRG, GST_DRP, GST_PRG,}},
#endif
  /* NTSC 60i -> 27.5 */
  {"3:2-4", 11, 10, 11, {GST_PRG, GST_PRG, GST_PRG, GST_PRG, GST_PRG,
              GST_PRG, GST_ONE, GST_INT, GST_INT, GST_INT,
          GST_ONE,}},
  /* PAL 50i -> 27.5 */
  {"1:2-4", 9, 9, 10, {GST_PRG, GST_PRG, GST_PRG, GST_PRG, GST_INT,
          GST_INT, GST_INT, GST_INT, GST_INT,}},
};

static const GEnumValue methods_types[] = {
  {GST_DEINTERLACE_TOMSMOCOMP, "Motion Adaptive: Motion Search",
      "tomsmocomp"},
  {GST_DEINTERLACE_GREEDY_H, "Motion Adaptive: Advanced Detection",
      "greedyh"},
  {GST_DEINTERLACE_GREEDY_L, "Motion Adaptive: Simple Detection", "greedyl"},
  {GST_DEINTERLACE_VFIR, "Blur Vertical", "vfir"},
  {GST_DEINTERLACE_LINEAR, "Television: Full resolution", "linear"},
  {GST_DEINTERLACE_LINEAR_BLEND, "Blur: Temporal (Do Not Use)",
      "linearblend"},
  {GST_DEINTERLACE_SCALER_BOB, "Double lines", "scalerbob"},
  {GST_DEINTERLACE_WEAVE, "Weave (Do Not Use)", "weave"},
  {GST_DEINTERLACE_WEAVE_TFF, "Progressive: Top Field First (Do Not Use)",
      "weavetff"},
  {GST_DEINTERLACE_WEAVE_BFF, "Progressive: Bottom Field First (Do Not Use)",
      "weavebff"},
  {0, NULL, NULL},
};

static const GEnumValue locking_types[] = {
  {GST_DEINTERLACE_LOCKING_NONE,
      "No pattern locking", "none"},
  {GST_DEINTERLACE_LOCKING_AUTO,
        "Choose passive/active locking depending on whether upstream is live",
      "auto"},
  {GST_DEINTERLACE_LOCKING_ACTIVE,
        "Block until pattern-locked. Use accurate timestamp interpolation within a pattern repeat.",
      "active"},
  {GST_DEINTERLACE_LOCKING_PASSIVE,
        "Do not block. Use naïve timestamp adjustment until pattern-locked based on state history.",
      "passive"},
  {0, NULL, NULL},
};


#define GST_TYPE_DEINTERLACE_METHODS (gst_deinterlace_methods_get_type ())
static GType
gst_deinterlace_methods_get_type (void)
{
  static GType deinterlace_methods_type = 0;

  if (!deinterlace_methods_type) {
    deinterlace_methods_type =
        g_enum_register_static ("GstDeinterlaceMethods", methods_types);
  }
  return deinterlace_methods_type;
}

#define GST_TYPE_DEINTERLACE_FIELDS (gst_deinterlace_fields_get_type ())
static GType
gst_deinterlace_fields_get_type (void)
{
  static GType deinterlace_fields_type = 0;

  static const GEnumValue fields_types[] = {
    {GST_DEINTERLACE_ALL, "All fields", "all"},
    {GST_DEINTERLACE_TF, "Top fields only", "top"},
    {GST_DEINTERLACE_BF, "Bottom fields only", "bottom"},
    {0, NULL, NULL},
  };

  if (!deinterlace_fields_type) {
    deinterlace_fields_type =
        g_enum_register_static ("GstDeinterlaceFields", fields_types);
  }
  return deinterlace_fields_type;
}

#define GST_TYPE_DEINTERLACE_FIELD_LAYOUT (gst_deinterlace_field_layout_get_type ())
static GType
gst_deinterlace_field_layout_get_type (void)
{
  static GType deinterlace_field_layout_type = 0;

  static const GEnumValue field_layout_types[] = {
    {GST_DEINTERLACE_LAYOUT_AUTO, "Auto detection", "auto"},
    {GST_DEINTERLACE_LAYOUT_TFF, "Top field first", "tff"},
    {GST_DEINTERLACE_LAYOUT_BFF, "Bottom field first", "bff"},
    {0, NULL, NULL},
  };

  if (!deinterlace_field_layout_type) {
    deinterlace_field_layout_type =
        g_enum_register_static ("GstDeinterlaceFieldLayout",
        field_layout_types);
  }
  return deinterlace_field_layout_type;
}

#define GST_TYPE_DEINTERLACE_MODES (gst_deinterlace_modes_get_type ())
static GType
gst_deinterlace_modes_get_type (void)
{
  static GType deinterlace_modes_type = 0;

  static const GEnumValue modes_types[] = {
    {GST_DEINTERLACE_MODE_AUTO, "Auto detection (best effort)", "auto"},
    {GST_DEINTERLACE_MODE_INTERLACED, "Force deinterlacing", "interlaced"},
    {GST_DEINTERLACE_MODE_DISABLED, "Run in passthrough mode", "disabled"},
    {GST_DEINTERLACE_MODE_AUTO_STRICT, "Auto detection (strict)",
        "auto-strict"},
    {0, NULL, NULL},
  };

  if (!deinterlace_modes_type) {
    deinterlace_modes_type =
        g_enum_register_static ("GstDeinterlaceModes", modes_types);
  }
  return deinterlace_modes_type;
}

#define GST_TYPE_DEINTERLACE_LOCKING (gst_deinterlace_locking_get_type ())
static GType
gst_deinterlace_locking_get_type (void)
{
  static GType deinterlace_locking_type = 0;

  if (!deinterlace_locking_type) {
    deinterlace_locking_type =
        g_enum_register_static ("GstDeinterlaceLocking", locking_types);
  }

  return deinterlace_locking_type;
}

#define DEINTERLACE_VIDEO_FORMATS \
    "{ AYUV, ARGB, ABGR, RGBA, BGRA, Y444, xRGB, xBGR, RGBx, BGRx, RGB, " \
    "BGR, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12, NV21 }"

#define DEINTERLACE_CAPS GST_VIDEO_CAPS_MAKE(DEINTERLACE_VIDEO_FORMATS)

#define DEINTERLACE_ALL_CAPS DEINTERLACE_CAPS ";" \
    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL)

static GstStaticCaps progressive_caps =
GST_STATIC_CAPS ("video/x-raw(ANY),interlace-mode=(string)progressive");
static GstStaticCaps deinterlace_caps = GST_STATIC_CAPS (DEINTERLACE_CAPS);

static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (DEINTERLACE_ALL_CAPS)
    );

static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (DEINTERLACE_ALL_CAPS)
    );

static void gst_deinterlace_finalize (GObject * self);
static void gst_deinterlace_set_property (GObject * self, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_deinterlace_get_property (GObject * self, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstCaps *gst_deinterlace_getcaps (GstDeinterlace * self, GstPad * pad,
    GstCaps * filter);
static gboolean gst_deinterlace_setcaps (GstDeinterlace * self, GstPad * pad,
    GstCaps * caps);
static gboolean gst_deinterlace_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_deinterlace_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstFlowReturn gst_deinterlace_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static GstStateChangeReturn gst_deinterlace_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_deinterlace_set_allocation (GstDeinterlace * self,
    GstBufferPool * pool, GstAllocator * allocator,
    GstAllocationParams * params);

static gboolean gst_deinterlace_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_deinterlace_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);

static GstFlowReturn gst_deinterlace_output_frame (GstDeinterlace * self,
    gboolean flushing);
static void gst_deinterlace_reset (GstDeinterlace * self);
static void gst_deinterlace_update_qos (GstDeinterlace * self,
    gdouble proportion, GstClockTimeDiff diff, GstClockTime time);
static void gst_deinterlace_reset_qos (GstDeinterlace * self);
static void gst_deinterlace_read_qos (GstDeinterlace * self,
    gdouble * proportion, GstClockTime * time);

#define IS_TELECINE(m) ((m) == GST_VIDEO_INTERLACE_MODE_MIXED && self->pattern > 1)

/* FIXME: what's the point of the childproxy interface here? What can you
 * actually do with it? The method objects seem to have no properties */
#if 0
static void gst_deinterlace_child_proxy_interface_init (gpointer g_iface,
    gpointer iface_data);

static void
_do_init (GType object_type)
{
  const GInterfaceInfo child_proxy_interface_info = {
    (GInterfaceInitFunc) gst_deinterlace_child_proxy_interface_init,
    NULL,                       /* interface_finalize */
    NULL                        /* interface_data */
  };

  g_type_add_interface_static (object_type, GST_TYPE_CHILD_PROXY,
      &child_proxy_interface_info);
}
#endif

G_DEFINE_TYPE (GstDeinterlace, gst_deinterlace, GST_TYPE_ELEMENT);

#define parent_class gst_deinterlace_parent_class

static const struct
{
  GType (*get_type) (void);
} _method_types[] = {
  {
  gst_deinterlace_method_tomsmocomp_get_type}, {
  gst_deinterlace_method_greedy_h_get_type}, {
  gst_deinterlace_method_greedy_l_get_type}, {
  gst_deinterlace_method_vfir_get_type}, {
  gst_deinterlace_method_linear_get_type}, {
  gst_deinterlace_method_linear_blend_get_type}, {
  gst_deinterlace_method_scaler_bob_get_type}, {
  gst_deinterlace_method_weave_get_type}, {
  gst_deinterlace_method_weave_tff_get_type}, {
  gst_deinterlace_method_weave_bff_get_type}
};

static void
gst_deinterlace_set_method (GstDeinterlace * self, GstDeinterlaceMethods method)
{
  GType method_type;
  gint width, height;
  GstVideoFormat format;

  GST_DEBUG_OBJECT (self, "Setting new method %d", method);

  width = GST_VIDEO_INFO_WIDTH (&self->vinfo);
  height = GST_VIDEO_INFO_HEIGHT (&self->vinfo);
  format = GST_VIDEO_INFO_FORMAT (&self->vinfo);

  if (self->method) {
    if (self->method_id == method &&
        gst_deinterlace_method_supported (G_TYPE_FROM_INSTANCE (self->method),
            format, width, height)) {
      GST_DEBUG_OBJECT (self, "Reusing current method");
      return;
    }
#if 0
    gst_child_proxy_child_removed (GST_OBJECT (self),
        GST_OBJECT (self->method));
    gst_object_unparent (GST_OBJECT (self->method));
    self->method = NULL;
#endif
  }

  method_type =
      _method_types[method].get_type !=
      NULL ? _method_types[method].get_type () : G_TYPE_INVALID;
  if (method_type == G_TYPE_INVALID
      || !gst_deinterlace_method_supported (method_type, format,
          width, height)) {
    GType tmp;
    gint i;

    method_type = G_TYPE_INVALID;

    GST_WARNING_OBJECT (self, "Method doesn't support requested format");
    for (i = 0; i < G_N_ELEMENTS (_method_types); i++) {
      if (_method_types[i].get_type == NULL)
        continue;
      tmp = _method_types[i].get_type ();
      if (gst_deinterlace_method_supported (tmp, format, width, height)) {
        GST_DEBUG_OBJECT (self, "Using method %d", i);
        method_type = tmp;
        method = i;
        break;
      }
    }
    /* If we get here we must have invalid caps! */
    g_assert (method_type != G_TYPE_INVALID);
  }

  self->method = g_object_new (method_type, "name", "method", NULL);
  self->method_id = method;

  gst_object_set_parent (GST_OBJECT (self->method), GST_OBJECT (self));
#if 0
  gst_child_proxy_child_added (GST_OBJECT (self), GST_OBJECT (self->method));
#endif

  if (self->method)
    gst_deinterlace_method_setup (self->method, &self->vinfo);
}

static gboolean
gst_deinterlace_clip_buffer (GstDeinterlace * self, GstBuffer * buffer)
{
  gboolean ret = TRUE;
  GstClockTime start, stop;
  guint64 cstart, cstop;

  GST_DEBUG_OBJECT (self,
      "Clipping buffer to the current segment: %" GST_TIME_FORMAT " -- %"
      GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
  GST_DEBUG_OBJECT (self, "Current segment: %" GST_SEGMENT_FORMAT,
      &self->segment);

  if (G_UNLIKELY (self->segment.format != GST_FORMAT_TIME))
    goto beach;
  if (G_UNLIKELY (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer)))
    goto beach;

  start = GST_BUFFER_TIMESTAMP (buffer);
  stop = start + GST_BUFFER_DURATION (buffer);

  if (!(ret = gst_segment_clip (&self->segment, GST_FORMAT_TIME,
              start, stop, &cstart, &cstop)))
    goto beach;

  GST_BUFFER_TIMESTAMP (buffer) = cstart;
  if (GST_CLOCK_TIME_IS_VALID (cstop))
    GST_BUFFER_DURATION (buffer) = cstop - cstart;

beach:
  if (ret)
    GST_DEBUG_OBJECT (self,
        "Clipped buffer to the current segment: %" GST_TIME_FORMAT " -- %"
        GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
  else
    GST_DEBUG_OBJECT (self, "Buffer outside the current segment -- dropping");

  return ret;
}

static void
gst_deinterlace_class_init (GstDeinterlaceClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  GstElementClass *element_class = (GstElementClass *) klass;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_templ));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_templ));

  gst_element_class_set_static_metadata (element_class,
      "Deinterlacer",
      "Filter/Effect/Video/Deinterlace",
      "Deinterlace Methods ported from DScaler/TvTime",
      "Martin Eikermann <meiker@upb.de>, "
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  gobject_class->set_property = gst_deinterlace_set_property;
  gobject_class->get_property = gst_deinterlace_get_property;
  gobject_class->finalize = gst_deinterlace_finalize;

  /**
   * GstDeinterlace:mode:
   *
   * This selects whether the deinterlacing methods should
   * always be applied or if they should only be applied
   * on content that has the "interlaced" flag on the caps.
   */
  g_object_class_install_property (gobject_class, PROP_MODE,
      g_param_spec_enum ("mode",
          "Mode",
          "Deinterlace Mode",
          GST_TYPE_DEINTERLACE_MODES,
          DEFAULT_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  /**
   * GstDeinterlace:method:
   *
   * Selects the different deinterlacing algorithms that can be used.
   * These provide different quality and CPU usage.
   *
   * Some methods provide parameters which can be set by getting
   * the "method" child via the #GstChildProxy interface and
   * setting the appropiate properties on it.
   *
   * <itemizedlist>
   * <listitem>
   * <para>
   * tomsmocomp
   * Motion Adaptive: Motion Search
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * greedyh
   * Motion Adaptive: Advanced Detection
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * greedyl
   * Motion Adaptive: Simple Detection
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * vfir
   * Blur vertical
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * linear
   * Linear interpolation
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * linearblend
   * Linear interpolation in time domain.  Any motion causes significant
   * ghosting, so this method should not be used.
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * scalerbob
   * Double lines
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * weave
   * Weave.  Bad quality, do not use.
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * weavetff
   * Progressive: Top Field First.  Bad quality, do not use.
   * </para>
   * </listitem>
   * <listitem>
   * <para>
   * weavebff
   * Progressive: Bottom Field First.  Bad quality, do not use.
   * </para>
   * </listitem>
   * </itemizedlist>
   */
  g_object_class_install_property (gobject_class, PROP_METHOD,
      g_param_spec_enum ("method",
          "Method",
          "Deinterlace Method",
          GST_TYPE_DEINTERLACE_METHODS,
          DEFAULT_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  /**
   * GstDeinterlace:fields:
   *
   * This selects which fields should be output. If "all" is selected
   * the output framerate will be double.
   */
  g_object_class_install_property (gobject_class, PROP_FIELDS,
      g_param_spec_enum ("fields",
          "fields",
          "Fields to use for deinterlacing",
          GST_TYPE_DEINTERLACE_FIELDS,
          DEFAULT_FIELDS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  /**
   * GstDeinterlace:layout:
   *
   * This selects which fields is the first in time.
   *
   */
  g_object_class_install_property (gobject_class, PROP_FIELD_LAYOUT,
      g_param_spec_enum ("tff",
          "tff",
          "Deinterlace top field first",
          GST_TYPE_DEINTERLACE_FIELD_LAYOUT,
          DEFAULT_FIELD_LAYOUT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  /**
   * GstDeinterlace:locking:
   *
   * This selects which approach to pattern locking is used which affects
   * processing latency and accuracy of timestamp adjustment for telecine
   * streams.
   */
  g_object_class_install_property (gobject_class, PROP_LOCKING,
      g_param_spec_enum ("locking", "locking", "Pattern locking mode",
          GST_TYPE_DEINTERLACE_LOCKING, DEFAULT_LOCKING,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstDeinterlace:ignore-obscure:
   *
   * This selects whether to ignore obscure/rare telecine patterns.
   * NTSC 2:3 pulldown variants are the only really common patterns.
   */
  g_object_class_install_property (gobject_class, PROP_IGNORE_OBSCURE,
      g_param_spec_boolean ("ignore-obscure", "ignore-obscure",
          "Ignore obscure telecine patterns (only consider P, I and 2:3 "
          "variants).", DEFAULT_IGNORE_OBSCURE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstDeinterlace:drop-orphans:
   *
   * This selects whether to drop orphan fields at the beginning of telecine
   * patterns in active locking mode.
   */
  g_object_class_install_property (gobject_class, PROP_DROP_ORPHANS,
      g_param_spec_boolean ("drop-orphans", "drop-orphans",
          "Drop orphan fields at the beginning of telecine patterns in "
          "active locking mode.", DEFAULT_DROP_ORPHANS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  element_class->change_state =
      GST_DEBUG_FUNCPTR (gst_deinterlace_change_state);
}

#if 0
static GstObject *
gst_deinterlace_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
    guint index)
{
  GstDeinterlace *self = GST_DEINTERLACE (child_proxy);

  g_return_val_if_fail (index == 0, NULL);

  return gst_object_ref (self->method);
}

static guint
gst_deinterlace_child_proxy_get_children_count (GstChildProxy * child_proxy)
{
  GstDeinterlace *self = GST_DEINTERLACE (child_proxy);

  return ((self->method) ? 1 : 0);
}

static void
gst_deinterlace_child_proxy_interface_init (gpointer g_iface,
    gpointer iface_data)
{
  GstChildProxyInterface *iface = g_iface;

  iface->get_child_by_index = gst_deinterlace_child_proxy_get_child_by_index;
  iface->get_children_count = gst_deinterlace_child_proxy_get_children_count;
}
#endif

static void
gst_deinterlace_init (GstDeinterlace * self)
{
  self->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
  gst_pad_set_chain_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace_chain));
  gst_pad_set_event_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace_sink_event));
  gst_pad_set_query_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace_sink_query));
  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);

  self->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
  gst_pad_set_event_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace_src_event));
  gst_pad_set_query_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_deinterlace_src_query));
  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);

  self->mode = DEFAULT_MODE;
  self->user_set_method_id = DEFAULT_METHOD;
  gst_video_info_init (&self->vinfo);
  gst_deinterlace_set_method (self, self->user_set_method_id);
  self->fields = DEFAULT_FIELDS;
  self->field_layout = DEFAULT_FIELD_LAYOUT;
  self->locking = DEFAULT_LOCKING;
  self->ignore_obscure = DEFAULT_IGNORE_OBSCURE;
  self->drop_orphans = DEFAULT_DROP_ORPHANS;

  self->low_latency = -1;
  self->pattern = -1;
  self->pattern_phase = -1;
  self->pattern_count = 0;
  self->output_count = 0;
  self->pattern_base_ts = GST_CLOCK_TIME_NONE;
  self->pattern_buf_dur = GST_CLOCK_TIME_NONE;
  self->still_frame_mode = FALSE;

  gst_deinterlace_reset (self);
}

static GstVideoFrame *
gst_video_frame_new_and_map (GstVideoInfo * vinfo, GstBuffer * buffer,
    GstMapFlags flags)
{
  GstVideoFrame *frame = g_malloc0 (sizeof (GstVideoFrame));
  gst_video_frame_map (frame, vinfo, buffer, flags);
  return frame;
}

static void
gst_video_frame_unmap_and_free (GstVideoFrame * frame)
{
  gst_video_frame_unmap (frame);
  g_free (frame);
}

static void
gst_deinterlace_reset_history (GstDeinterlace * self, gboolean drop_all)
{
  gint i;

  if (!drop_all) {
    GST_DEBUG_OBJECT (self, "Flushing history (count %d)", self->history_count);
    while (self->history_count > 0) {
      if (gst_deinterlace_output_frame (self, TRUE) != GST_FLOW_OK) {
        /* Encountered error, or flushing -> skip and drop all remaining */
        drop_all = TRUE;
        break;
      }
    }
  }
  if (drop_all) {
    GST_DEBUG_OBJECT (self, "Resetting history (count %d)",
        self->history_count);

    for (i = 0; i < self->history_count; i++) {
      if (self->field_history[i].frame) {
        gst_video_frame_unmap_and_free (self->field_history[i].frame);
        self->field_history[i].frame = NULL;
      }
    }
  }
  memset (self->field_history, 0,
      GST_DEINTERLACE_MAX_FIELD_HISTORY * sizeof (GstDeinterlaceField));
  self->history_count = 0;
  memset (self->buf_states, 0,
      GST_DEINTERLACE_MAX_BUFFER_STATE_HISTORY *
      sizeof (GstDeinterlaceBufferState));
  self->state_count = 0;
  self->pattern_lock = FALSE;
  self->pattern_refresh = TRUE;
  self->cur_field_idx = -1;

  if (!self->still_frame_mode && self->last_buffer) {
    gst_buffer_unref (self->last_buffer);
    self->last_buffer = NULL;
  }
}

static void
gst_deinterlace_reset (GstDeinterlace * self)
{
  GST_DEBUG_OBJECT (self, "Resetting internal state");

  gst_video_info_init (&self->vinfo);

  self->passthrough = FALSE;

  self->reconfigure = FALSE;
  if ((gint) self->new_mode != -1)
    self->mode = self->new_mode;
  if ((gint) self->new_fields != -1)
    self->fields = self->new_fields;
  self->new_mode = -1;
  self->new_fields = -1;

  gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);

  if (self->request_caps)
    gst_caps_unref (self->request_caps);
  self->request_caps = NULL;

  gst_deinterlace_reset_history (self, TRUE);

  gst_deinterlace_reset_qos (self);

  self->need_more = FALSE;
  self->have_eos = FALSE;

  gst_deinterlace_set_allocation (self, NULL, NULL, NULL);
}

static void
gst_deinterlace_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDeinterlace *self;

  self = GST_DEINTERLACE (object);

  switch (prop_id) {
    case PROP_MODE:{
      gint new_mode;

      GST_OBJECT_LOCK (self);
      new_mode = g_value_get_enum (value);
      if (self->mode != new_mode && gst_pad_has_current_caps (self->srcpad)) {
        self->reconfigure = TRUE;
        self->new_mode = new_mode;
      } else {
        self->mode = new_mode;
      }
      GST_OBJECT_UNLOCK (self);
      break;
    }
    case PROP_METHOD:
      self->user_set_method_id = g_value_get_enum (value);
      gst_deinterlace_set_method (self, self->user_set_method_id);
      break;
    case PROP_FIELDS:{
      gint new_fields;

      GST_OBJECT_LOCK (self);
      new_fields = g_value_get_enum (value);
      if (self->fields != new_fields && gst_pad_has_current_caps (self->srcpad)) {
        self->reconfigure = TRUE;
        self->new_fields = new_fields;
      } else {
        self->fields = new_fields;
      }
      GST_OBJECT_UNLOCK (self);
      break;
    }
    case PROP_FIELD_LAYOUT:
      self->field_layout = g_value_get_enum (value);
      break;
    case PROP_LOCKING:
      self->locking = g_value_get_enum (value);
      break;
    case PROP_IGNORE_OBSCURE:
      self->ignore_obscure = g_value_get_boolean (value);
      break;
    case PROP_DROP_ORPHANS:
      self->drop_orphans = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
  }

}

static void
gst_deinterlace_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstDeinterlace *self;

  self = GST_DEINTERLACE (object);

  switch (prop_id) {
    case PROP_MODE:
      g_value_set_enum (value, self->mode);
      break;
    case PROP_METHOD:
      g_value_set_enum (value, self->user_set_method_id);
      break;
    case PROP_FIELDS:
      g_value_set_enum (value, self->fields);
      break;
    case PROP_FIELD_LAYOUT:
      g_value_set_enum (value, self->field_layout);
      break;
    case PROP_LOCKING:
      g_value_set_enum (value, self->locking);
      break;
    case PROP_IGNORE_OBSCURE:
      g_value_set_boolean (value, self->ignore_obscure);
      break;
    case PROP_DROP_ORPHANS:
      g_value_set_boolean (value, self->drop_orphans);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
  }
}

static void
gst_deinterlace_finalize (GObject * object)
{
  GstDeinterlace *self = GST_DEINTERLACE (object);

  gst_deinterlace_reset (self);

  if (self->method) {
    gst_object_unparent (GST_OBJECT (self->method));
    self->method = NULL;
  }

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

static void
gst_deinterlace_update_pattern_timestamps (GstDeinterlace * self)
{
  gint state_idx;
  if (self->low_latency) {
    /* in low-latency mode the buffer state history contains old buffer
     * states as well as the current one and perhaps some future ones.
     * the current buffer's state is given by the number of field pairs
     * rounded up, minus 1. the below is equivalent */
    state_idx = (self->history_count - 1) >> 1;
  } else {
    /* in high-latency mode state_count - 1 is the current buffer's state */
    state_idx = self->state_count - 1;
  }

  self->pattern_base_ts = self->buf_states[state_idx].timestamp;
  if (self->buf_states[state_idx].state != GST_RFF) {
    self->pattern_buf_dur =
        (self->buf_states[state_idx].duration *
        telecine_patterns[self->pattern].ratio_d) /
        telecine_patterns[self->pattern].ratio_n;
  } else {
    self->pattern_buf_dur =
        (self->buf_states[state_idx].duration *
        telecine_patterns[self->pattern].ratio_d * 2) /
        (telecine_patterns[self->pattern].ratio_n * 3);
  }
  GST_DEBUG_OBJECT (self,
      "Starting a new pattern repeat with base ts %" GST_TIME_FORMAT
      " and dur %" GST_TIME_FORMAT, GST_TIME_ARGS (self->pattern_base_ts),
      GST_TIME_ARGS (self->pattern_buf_dur));
}

static GstVideoFrame *
gst_deinterlace_pop_history (GstDeinterlace * self)
{
  GstVideoFrame *frame;

  g_return_val_if_fail (self->history_count > 0, NULL);

  GST_DEBUG_OBJECT (self, "Pop last history frame -- current history size %d",
      self->history_count);

  frame = self->field_history[self->history_count - 1].frame;

  self->history_count--;
  if (self->locking != GST_DEINTERLACE_LOCKING_NONE && (!self->history_count
          || GST_VIDEO_FRAME_PLANE_DATA (frame, 0) !=
          GST_VIDEO_FRAME_PLANE_DATA (self->field_history[self->history_count -
                  1].frame, 0))) {
    if (!self->low_latency)
      self->state_count--;
    if (self->pattern_lock) {
      self->pattern_count++;
      if (self->pattern != -1
          && self->pattern_count >= telecine_patterns[self->pattern].length) {
        self->pattern_count = 0;
        self->output_count = 0;
      }
    }
  }

  GST_DEBUG_OBJECT (self, "Returning frame: %p %" GST_TIME_FORMAT
      " with duration %" GST_TIME_FORMAT " and size %" G_GSIZE_FORMAT, frame,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (frame->buffer)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (frame->buffer)),
      GST_VIDEO_FRAME_SIZE (frame));

  return frame;
}

static void
gst_deinterlace_get_buffer_state (GstDeinterlace * self, GstVideoFrame * frame,
    guint8 * state, GstVideoInterlaceMode * i_mode)
{
  GstVideoInterlaceMode interlacing_mode;

  if (!(i_mode || state))
    return;

  interlacing_mode = GST_VIDEO_INFO_INTERLACE_MODE (&frame->info);
  if (self->mode == GST_DEINTERLACE_MODE_INTERLACED)
    interlacing_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;

  if (state) {
    if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED) {
      if (GST_VIDEO_FRAME_IS_RFF (frame)) {
        *state = GST_DEINTERLACE_BUFFER_STATE_RFF;
      } else if (GST_VIDEO_FRAME_IS_ONEFIELD (frame)) {
        /* tc top if tff, tc bottom otherwise */
        if (GST_VIDEO_FRAME_IS_TFF (frame)) {
          *state = GST_DEINTERLACE_BUFFER_STATE_TC_T;
        } else {
          *state = GST_DEINTERLACE_BUFFER_STATE_TC_B;
        }
      } else if (GST_VIDEO_FRAME_IS_INTERLACED (frame)) {
        *state = GST_DEINTERLACE_BUFFER_STATE_TC_M;
      } else {
        *state = GST_DEINTERLACE_BUFFER_STATE_TC_P;
      }
    } else {
      if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED) {
        *state = GST_DEINTERLACE_BUFFER_STATE_I;
      } else {
        *state = GST_DEINTERLACE_BUFFER_STATE_P;
      }
    }
  }

  if (i_mode)
    *i_mode = interlacing_mode;
}

#define STATE_TO_STRING(s) ((s) == GST_DEINTERLACE_BUFFER_STATE_P ? "P" : \
  (s) == GST_DEINTERLACE_BUFFER_STATE_I ? "I" : \
  (s) == GST_DEINTERLACE_BUFFER_STATE_TC_B ? "B" : \
  (s) == GST_DEINTERLACE_BUFFER_STATE_TC_T ? "T" : \
  (s) == GST_DEINTERLACE_BUFFER_STATE_TC_P ? "TCP" : \
  (s) == GST_DEINTERLACE_BUFFER_STATE_TC_M ? "TCM" : "RFF")

#define MODE_TO_STRING(m) ((m) == GST_VIDEO_INTERLACE_MODE_MIXED ? "MIXED" : \
  (m) == GST_VIDEO_INTERLACE_MODE_INTERLEAVED ? "I" : \
  (m) == GST_VIDEO_INTERLACE_MODE_FIELDS ? "FIELDS" : "P")

static void
gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer)
{
  int i = 1;
  GstDeinterlaceFieldLayout field_layout = self->field_layout;
  gboolean tff;
  gboolean onefield;
  GstVideoFrame *frame = NULL;
  GstVideoFrame *field1, *field2 = NULL;
  guint fields_to_push;
  gint field1_flags, field2_flags;
  GstVideoInterlaceMode interlacing_mode;
  guint8 buf_state;

  /* we will only read from this buffer and write into fresh output buffers
   * if this is not the case, change the map flags as appropriate
   */
  frame = gst_video_frame_new_and_map (&self->vinfo, buffer, GST_MAP_READ);
  /* we can manage the buffer ref count using the maps from here on */
  gst_buffer_unref (buffer);

  tff = GST_VIDEO_FRAME_IS_TFF (frame);
  onefield = GST_VIDEO_FRAME_IS_ONEFIELD (frame);
  fields_to_push = (onefield) ? 1 : 2;

  g_return_if_fail (self->history_count <
      GST_DEINTERLACE_MAX_FIELD_HISTORY - fields_to_push);

  gst_deinterlace_get_buffer_state (self, frame, &buf_state, &interlacing_mode);

  GST_DEBUG_OBJECT (self,
      "Pushing new frame as %d fields to the history (count before %d): ptr %p at %"
      GST_TIME_FORMAT " with duration %" GST_TIME_FORMAT
      ", size %" G_GSIZE_FORMAT ", state %s, interlacing mode %s",
      fields_to_push, self->history_count, frame,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)),
      gst_buffer_get_size (buffer),
      STATE_TO_STRING (buf_state), MODE_TO_STRING (interlacing_mode));

  /* move up for new state */
  memmove (&self->buf_states[1], &self->buf_states[0],
      (GST_DEINTERLACE_MAX_BUFFER_STATE_HISTORY - 1) *
      sizeof (GstDeinterlaceBufferState));
  self->buf_states[0].state = buf_state;
  self->buf_states[0].timestamp = GST_BUFFER_TIMESTAMP (buffer);
  self->buf_states[0].duration = GST_BUFFER_DURATION (buffer);
  if (self->state_count < GST_DEINTERLACE_MAX_BUFFER_STATE_HISTORY)
    self->state_count++;

  for (i = GST_DEINTERLACE_MAX_FIELD_HISTORY - 1; i >= fields_to_push; i--) {
    self->field_history[i].frame =
        self->field_history[i - fields_to_push].frame;
    self->field_history[i].flags =
        self->field_history[i - fields_to_push].flags;
  }

  if (field_layout == GST_DEINTERLACE_LAYOUT_AUTO) {
    if (!GST_VIDEO_INFO_IS_INTERLACED (&self->vinfo)) {
      GST_WARNING_OBJECT (self, "Can't detect field layout -- assuming TFF");
      field_layout = GST_DEINTERLACE_LAYOUT_TFF;
    } else if (tff) {
      field_layout = GST_DEINTERLACE_LAYOUT_TFF;
    } else {
      field_layout = GST_DEINTERLACE_LAYOUT_BFF;
    }
  }

  field1 = frame;
  field2 = gst_video_frame_new_and_map (&self->vinfo, buffer, GST_MAP_READ);
  if (field_layout == GST_DEINTERLACE_LAYOUT_TFF) {
    GST_DEBUG_OBJECT (self, "Top field first");
    field1_flags = PICTURE_INTERLACED_TOP;
    field2_flags = PICTURE_INTERLACED_BOTTOM;
  } else {
    GST_DEBUG_OBJECT (self, "Bottom field first");
    field1_flags = PICTURE_INTERLACED_BOTTOM;
    field2_flags = PICTURE_INTERLACED_TOP;
  }

  if (!onefield) {
    GST_DEBUG_OBJECT (self, "Two fields");
    self->field_history[1].frame = field1;
    self->field_history[1].flags = field1_flags;

    self->field_history[0].frame = field2;
    self->field_history[0].flags = field2_flags;
  } else {                      /* onefield */
    GST_DEBUG_OBJECT (self, "One field");
    self->field_history[0].frame = field1;
    self->field_history[0].flags = field1_flags;
    gst_video_frame_unmap_and_free (field2);
  }

  self->history_count += fields_to_push;
  self->cur_field_idx += fields_to_push;

  GST_DEBUG_OBJECT (self, "Pushed buffer -- current history size %d, index %d",
      self->history_count, self->cur_field_idx);

  if (self->last_buffer)
    gst_buffer_unref (self->last_buffer);
  self->last_buffer = gst_buffer_ref (buffer);
}

static void
gst_deinterlace_update_qos (GstDeinterlace * self, gdouble proportion,
    GstClockTimeDiff diff, GstClockTime timestamp)
{
  GST_DEBUG_OBJECT (self,
      "Updating QoS: proportion %lf, diff %" GST_STIME_FORMAT ", timestamp %"
      GST_TIME_FORMAT, proportion, GST_STIME_ARGS (diff),
      GST_TIME_ARGS (timestamp));

  GST_OBJECT_LOCK (self);
  self->proportion = proportion;
  if (G_LIKELY (timestamp != GST_CLOCK_TIME_NONE)) {
    if (G_UNLIKELY (diff > 0))
      self->earliest_time =
          timestamp + 2 * diff + ((self->fields ==
              GST_DEINTERLACE_ALL) ? self->field_duration : 2 *
          self->field_duration);
    else
      self->earliest_time = timestamp + diff;
  } else {
    self->earliest_time = GST_CLOCK_TIME_NONE;
  }
  GST_OBJECT_UNLOCK (self);
}

static void
gst_deinterlace_reset_qos (GstDeinterlace * self)
{
  gst_deinterlace_update_qos (self, 0.5, 0, GST_CLOCK_TIME_NONE);
  self->processed = 0;
  self->dropped = 0;
}

static void
gst_deinterlace_read_qos (GstDeinterlace * self, gdouble * proportion,
    GstClockTime * time)
{
  GST_OBJECT_LOCK (self);
  *proportion = self->proportion;
  *time = self->earliest_time;
  GST_OBJECT_UNLOCK (self);
}

/* Perform qos calculations before processing the next frame. Returns TRUE if
 * the frame should be processed, FALSE if the frame can be dropped entirely */
static gboolean
gst_deinterlace_do_qos (GstDeinterlace * self, const GstBuffer * buffer)
{
  GstClockTime qostime, earliest_time;
  GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
  gdouble proportion;

  /* no timestamp, can't do QoS => process frame */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
    GST_LOG_OBJECT (self, "invalid timestamp, can't do QoS, process frame");
    goto keep_frame;
  }

  /* get latest QoS observation values */
  gst_deinterlace_read_qos (self, &proportion, &earliest_time);

  /* skip qos if we have no observation (yet) => process frame */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
    GST_LOG_OBJECT (self, "no observation yet, process frame");
    goto keep_frame;
  }

  /* qos is done on running time */
  qostime = gst_segment_to_running_time (&self->segment, GST_FORMAT_TIME,
      timestamp);

  /* see how our next timestamp relates to the latest qos timestamp */
  GST_LOG_OBJECT (self, "qostime %" GST_TIME_FORMAT ", earliest %"
      GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));

  if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
    GstClockTime stream_time, jitter;
    GstMessage *qos_msg;

    GST_DEBUG_OBJECT (self, "we are late, drop frame");
    self->dropped++;
    stream_time =
        gst_segment_to_stream_time (&self->segment, GST_FORMAT_TIME, timestamp);
    jitter = GST_CLOCK_DIFF (qostime, earliest_time);
    qos_msg =
        gst_message_new_qos (GST_OBJECT (self), FALSE, qostime, stream_time,
        timestamp, GST_BUFFER_DURATION (buffer));
    gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
    gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
        self->processed, self->dropped);
    gst_element_post_message (GST_ELEMENT (self), qos_msg);
    return FALSE;
  }

  GST_LOG_OBJECT (self, "process frame");
keep_frame:
  self->processed++;
  return TRUE;
}

static gboolean
gst_deinterlace_fix_timestamps (GstDeinterlace * self,
    GstVideoFrame * field1, GstVideoFrame * field2)
{
  GstVideoFrame *field3, *field4;
  GstVideoInterlaceMode interlacing_mode;

  if (self->pattern_lock && self->pattern > -1) {
    /* accurate pattern-locked timestamp adjustment */
    if (!self->pattern_count)
      gst_deinterlace_update_pattern_timestamps (self);

    GST_BUFFER_TIMESTAMP (field1->buffer) =
        self->pattern_base_ts + self->output_count * self->pattern_buf_dur;
    GST_BUFFER_DURATION (field1->buffer) = self->pattern_buf_dur;
    self->output_count++;
  } else {
    /* naive (but low-latency) timestamp adjustment based on subsequent
     * fields/buffers */
    if (field2
        && GST_VIDEO_FRAME_PLANE_DATA (field1,
            0) != GST_VIDEO_FRAME_PLANE_DATA (field2, 0)) {
      if (GST_BUFFER_TIMESTAMP (field1->buffer) +
          GST_BUFFER_DURATION (field1->buffer) ==
          GST_BUFFER_TIMESTAMP (field2->buffer)) {
        GST_BUFFER_TIMESTAMP (field1->buffer) =
            GST_BUFFER_TIMESTAMP (field2->buffer) =
            (GST_BUFFER_TIMESTAMP (field1->buffer) +
            GST_BUFFER_TIMESTAMP (field2->buffer)) / 2;
      } else {
        GST_BUFFER_TIMESTAMP (field2->buffer) =
            GST_BUFFER_TIMESTAMP (field1->buffer);
      }
    }

    if (self->history_count < 3) {
      GST_DEBUG_OBJECT (self, "Need more fields (have %d, need 3)",
          self->history_count);
      return FALSE;
    }

    field3 = self->field_history[self->history_count - 3].frame;
    interlacing_mode = GST_VIDEO_INFO_INTERLACE_MODE (&field3->info);
    if (IS_TELECINE (interlacing_mode)) {
      if (self->history_count < 4) {
        GST_DEBUG_OBJECT (self, "Need more fields (have %d, need 4)",
            self->history_count);
        return FALSE;
      }

      field4 = self->field_history[self->history_count - 4].frame;
      if (GST_VIDEO_FRAME_PLANE_DATA (field3,
              0) != GST_VIDEO_FRAME_PLANE_DATA (field4, 0)) {
        /* telecine fields in separate buffers */
        GST_BUFFER_TIMESTAMP (field3->buffer) =
            (GST_BUFFER_TIMESTAMP (field3->buffer) +
            GST_BUFFER_TIMESTAMP (field4->buffer)) / 2;
      }
    }

    GST_BUFFER_DURATION (field1->buffer) =
        GST_BUFFER_TIMESTAMP (field3->buffer) -
        GST_BUFFER_TIMESTAMP (field1->buffer);
  }

  GST_DEBUG_OBJECT (self,
      "Field 1 adjusted to ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (field1->buffer)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (field1->buffer)));
  return TRUE;
}

static void
gst_deinterlace_get_pattern_lock (GstDeinterlace * self, gboolean * flush_one)
{
  /* loop over all possible patterns and all possible phases
   * giving each a score. the highest score gets the lock */
  /* the score is calculated as the number of matched buffers in the
   * sequence starting at the phase offset with those from the history
   * then the longest duration pattern match is taken. if there is more than
   * one pattern matching all buffers, we take the longest pattern of those.
   * matches to complete patterns are preferred. if no non-trivial pattern is
   * matched, trivial patterns are tested. */
  gint i, j, k, score, pattern, phase;
  const gint state_count = self->state_count;
  const gint n_required = self->ignore_obscure ?
      GST_DEINTERLACE_OBSCURE_THRESHOLD :
      GST_DEINTERLACE_MAX_BUFFER_STATE_HISTORY;

  /* set unknown pattern as this is used in logic outside this function */
  self->pattern = -1;

  /* wait for more buffers */
  if (!self->have_eos && state_count < n_required) {
    GST_DEBUG_OBJECT (self, "Need more buffers in state history - %d/%d",
        state_count, n_required);
    return;
  }

  score = pattern = phase = -1;

  /* loop over all patterns */
  for (i = 0; i < G_N_ELEMENTS (telecine_patterns); i++) {
    const guint8 length = telecine_patterns[i].length;

    if (self->ignore_obscure && i >= GST_DEINTERLACE_OBSCURE_THRESHOLD)
      break;

    if (state_count < length)
      continue;

    /* loop over all phases */
    for (j = 0; j < length; j++) {
      /* low-latency mode looks at past buffers, high latency at future buffers */
      const gint state_idx =
          self->low_latency ? (self->history_count - 1) >> 1 : state_count - 1;
      /* loop over history, breaking on differing buffer states */
      for (k = 0; k < length && k < state_count; k++) {
        const guint8 hist = self->buf_states[state_idx - k].state;
        const guint8 patt = telecine_patterns[i].states[(j + k) % length];
        if (!(hist & patt))
          break;
      }

      /* make complete matches more signficant */
      if (k == length)
        k += GST_DEINTERLACE_MAX_BUFFER_STATE_HISTORY;

      /* take as new best pattern if the number of matched buffers is more than
       * for other patterns */
      if (k > score) {
        score = k;
        pattern = i;
        phase = j;
      }
    }
  }

  if (pattern < 0) {
    GST_WARNING_OBJECT (self, "Failed to select a pattern");
    return;
  }

  GST_DEBUG_OBJECT (self,
      "Final pattern match result: pa %d, ph %d, l %d, s %d", pattern, phase,
      telecine_patterns[pattern].length, score);
  self->pattern = pattern;
  self->pattern_phase = phase;
  self->pattern_count = 0;
  self->output_count = 0;
  self->pattern_lock = TRUE;

  for (i = 0; i < telecine_patterns[pattern].length; i++) {
    gint state_idx =
        self->low_latency ? (self->history_count - 1) >> 1 : self->state_count -
        1;
    state_idx -= i;
    GST_LOG_OBJECT (self, "buf[%d] %s", i,
        STATE_TO_STRING (self->buf_states[state_idx].state));
  }

  /* check for the case that the first field of the pattern is an orphan */
  if (pattern > 1
      && telecine_patterns[pattern].states[phase] & (GST_ONE | GST_INT)) {
    gint i = phase, field_count = 0;
    guint8 state = telecine_patterns[pattern].states[i];

    do {
      if (state & GST_ONE) {
        field_count++;
#if 0
      } else if (!(state & GST_DRP)) {
#endif
      } else {
        field_count += 2;
      }
      i++;
      i %= telecine_patterns[pattern].length;
      state = telecine_patterns[pattern].states[i];
    } while (!(state & GST_PRG));

    /* if field_count is odd, we have an orphan field at the beginning of the
     * sequence
     * note - don't do this in low-latency mode as we are somewhere within the
     * pattern already */
    if (!self->low_latency && (*flush_one = field_count & 1)) {
      GST_DEBUG_OBJECT (self, "Orphan field detected at the beginning of the "
          "pattern - it will be deinterlaced.");
    }
  }
}

static GstFlowReturn
gst_deinterlace_output_frame (GstDeinterlace * self, gboolean flushing)
{
  GstClockTime timestamp;
  GstFlowReturn ret;
  gint fields_required;
  GstBuffer *buf, *outbuf;
  GstVideoFrame *outframe = NULL;
  GstDeinterlaceField *field1, *field2;
  GstVideoInterlaceMode interlacing_mode;
  guint8 buf_state;
  gboolean hl_no_lock;          /* indicates high latency timestamp adjustment but no pattern lock (could be ONEF or I) */
  gboolean same_buffer;         /* are field1 and field2 in the same buffer? */
  gboolean flush_one;           /* used for flushing one field when in high latency mode and not locked */
  TelecinePattern pattern;
  guint8 phase, count;
  const GstDeinterlaceLocking locking = self->locking;

  memset (&pattern, 0, sizeof (pattern));

restart:
  ret = GST_FLOW_OK;
  hl_no_lock = FALSE;
  flush_one = FALSE;
  self->need_more = FALSE;
  phase = self->pattern_phase;
  count = self->pattern_count;

  if (!self->history_count) {
    GST_DEBUG_OBJECT (self, "History is empty, waiting for more buffers!");
    goto need_more;
  }

  field1 = &self->field_history[self->history_count - 1];

  if (locking != GST_DEINTERLACE_LOCKING_NONE) {
    GstCaps *sinkcaps;

    if (!self->state_count) {
      GST_ERROR_OBJECT (self,
          "BROKEN! Fields in history + no states should not happen!");
      return GST_FLOW_ERROR;
    }

    gst_deinterlace_get_buffer_state (self, field1->frame, &buf_state,
        &interlacing_mode);

    if (self->pattern != -1)
      pattern = telecine_patterns[self->pattern];

    /* patterns 0 and 1 are interlaced, the rest are telecine */
    if (self->pattern > 1)
      interlacing_mode = GST_VIDEO_INTERLACE_MODE_MIXED;

    if (self->pattern == -1 || self->pattern_refresh
        || !(buf_state & pattern.states[(phase + count) % pattern.length])) {
      if (self->pattern == -1) {
        GST_DEBUG_OBJECT (self, "No pattern lock - refresh lock");
      } else if (self->pattern_refresh) {
        GST_DEBUG_OBJECT (self, "Pattern refresh - refresh lock");
      } else {
        GST_DEBUG_OBJECT (self, "Unexpected buffer state - refresh lock");
      }
      /* no pattern, pattern refresh set or unexpected buffer state */
      self->pattern_lock = FALSE;
      self->pattern_refresh = TRUE;

      /* refresh pattern lock */
      gst_deinterlace_get_pattern_lock (self, &flush_one);

      if (self->pattern != -1) {
        /* locked onto a valid pattern so refresh complete */
        GST_DEBUG_OBJECT (self, "Pattern locked! %s starting at %d",
            telecine_patterns[self->pattern].nick, self->pattern_phase);
        self->pattern_refresh = FALSE;
      } else if (!self->low_latency) {
        if (!self->pattern_lock) {
          goto need_more;
        } else {
          hl_no_lock = TRUE;
        }
      }

      /* setcaps on sink and src pads */
      sinkcaps = gst_pad_get_current_caps (self->sinkpad);
      if (!gst_deinterlace_setcaps (self, self->sinkpad, sinkcaps)) {
        gst_caps_unref (sinkcaps);
        return GST_FLOW_NOT_NEGOTIATED;
      }

      gst_caps_unref (sinkcaps);

      if (flush_one && self->drop_orphans) {
        GST_DEBUG_OBJECT (self, "Dropping orphan first field");
        self->cur_field_idx--;
        gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
        goto restart;
      }
    }
  } else {
    gst_deinterlace_get_buffer_state (self, field1->frame, NULL,
        &interlacing_mode);
  }

  same_buffer = self->history_count >= 2
      && (GST_VIDEO_FRAME_PLANE_DATA (field1->frame, 0) ==
      GST_VIDEO_FRAME_PLANE_DATA (self->field_history[self->history_count -
              2].frame, 0));

  if ((flushing && self->history_count == 1) || (flush_one
          && !self->drop_orphans) || (hl_no_lock && (self->history_count == 1
              || !same_buffer))) {
    /* This case is for flushing a single field:
     * - flushing and 1 field in the history
     * - flush one (due to orphans in the pattern) and do not drop orphans
     * - high-latency pattern locking with no possible lock given the current
     *   state and either only one field in the history or the tip two fields
     *   are in separate buffers */
    GST_DEBUG_OBJECT (self, "Flushing one field using linear method");
    gst_deinterlace_set_method (self, GST_DEINTERLACE_LINEAR);
    fields_required = gst_deinterlace_method_get_fields_required (self->method);
  } else if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_PROGRESSIVE ||
      (interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED &&
          !GST_VIDEO_FRAME_IS_INTERLACED (field1->frame))) {
    /* This case is for processing progressive buffers, telecine or plain
     * progressive */
    GstVideoFrame *field1_frame;
    GstBuffer *field1_buffer;

    /* progressive */
    fields_required = 2;

    /* Not enough fields in the history */
    if (!flushing && self->history_count < fields_required) {
      GST_DEBUG_OBJECT (self, "Need more fields (have %d, need %d)",
          self->history_count, self->cur_field_idx + fields_required);
      goto need_more;
    }

    field2 = &self->field_history[self->history_count - 2];
    if (GST_VIDEO_FRAME_PLANE_DATA (field1->frame,
            0) != GST_VIDEO_FRAME_PLANE_DATA (field2->frame, 0)) {
      /* ERROR - next two fields in field history are not one progressive buffer - weave? */
      GST_ERROR_OBJECT (self,
          "Progressive buffer but two fields at tip aren't in the same buffer!");
    }

    if (IS_TELECINE (interlacing_mode)
        && !gst_deinterlace_fix_timestamps (self, field1->frame, field2->frame)
        && !flushing)
      goto need_more;

    GST_DEBUG_OBJECT (self,
        "Frame type: Progressive; pushing buffer as a frame");
    /* pop and push */
    self->cur_field_idx--;
    field1_frame = gst_deinterlace_pop_history (self);
    field1_buffer = field1_frame->buffer;
    gst_buffer_ref (field1_buffer);
    gst_video_frame_unmap_and_free (field1_frame);
    /* field2 is the same buffer as field1, but we need to remove it from the
     * history anyway */
    self->cur_field_idx--;
    gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
    GST_DEBUG_OBJECT (self,
        "[OUT] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
        GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (field1_buffer)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (field1_buffer)),
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (field1_buffer) +
            GST_BUFFER_DURATION (field1_buffer)));
    return gst_pad_push (self->srcpad, field1_buffer);
  } else if (IS_TELECINE (interlacing_mode)
      && GST_VIDEO_FRAME_IS_INTERLACED (field1->frame) && !same_buffer) {
    /* This case needs to identify telecine mixed buffers that require weaving
     * of two fields in different buffers.
     * - interlacing mode is mixed
     * - locked on to a telecine pattern
     * - frame is interlaced
     * - fields are in separate buffers
     * If we don't yet have a pattern lock, we will have to deinterlace as we
     * don't explicitly know we have a telecine sequence and so we drop through
     * to the plain deinterlace case */
    fields_required = 2;
    if (!flushing && self->history_count < fields_required) {
      GST_DEBUG_OBJECT (self, "Need more fields (have %d, need %d)",
          self->history_count, self->cur_field_idx + fields_required);
      goto need_more;
    }

    field2 = &self->field_history[self->history_count - 2];
    if (!gst_deinterlace_fix_timestamps (self, field1->frame, field2->frame)
        && !flushing)
      goto need_more;

    /* check field1 and field2 buffer caps and flags are corresponding */
    if (field1->flags == field2->flags) {
      /* ERROR - fields are of same parity - what should be done here?
       * perhaps deinterlace the tip field and start again? */
      GST_ERROR_OBJECT (self, "Telecine mixed with fields of same parity!");
    }
    GST_DEBUG_OBJECT (self,
        "Frame type: Telecine Mixed; weaving tip two fields into a frame");
    /* set method to WEAVE */
    gst_deinterlace_set_method (self, GST_DEINTERLACE_WEAVE);
  } else {
    /* This is the final catch-all case that applies the selected deinterlacing
     * method. At this point the fields to be processed are either definitely
     * interlaced or we do not yet know that we have a telecine pattern lock
     * and so the best we can do is to deinterlace the fields. */
    gst_deinterlace_set_method (self, self->user_set_method_id);
    fields_required = gst_deinterlace_method_get_fields_required (self->method);
    if (flushing && self->history_count < fields_required) {
      /* note: we already checked for flushing with history count == 1 above
       * so we must have 2 or more fields in here */
      gst_deinterlace_set_method (self, GST_DEINTERLACE_VFIR);
      fields_required =
          gst_deinterlace_method_get_fields_required (self->method);
      GST_DEBUG_OBJECT (self, "Flushing field(s) using %s method",
          methods_types[self->method_id].value_nick);
    }

    /* Not enough fields in the history */
    if (!flushing && self->history_count < fields_required) {
      GST_DEBUG_OBJECT (self, "Need more fields (have %d, need %d)",
          self->history_count, self->cur_field_idx + fields_required);
      goto need_more;
    }

    GST_DEBUG_OBJECT (self,
        "Frame type: Interlaced; deinterlacing using %s method",
        methods_types[self->method_id].value_nick);
  }

  if (!flushing && self->cur_field_idx < 1) {
    goto need_more;
  } else if (self->cur_field_idx < 0 && flushing) {
    self->cur_field_idx++;
  }

  if (self->fields == GST_DEINTERLACE_ALL || IS_TELECINE (interlacing_mode))
    GST_DEBUG_OBJECT (self, "All fields");
  else if (self->fields == GST_DEINTERLACE_TF)
    GST_DEBUG_OBJECT (self, "Top fields");
  else if (self->fields == GST_DEINTERLACE_BF)
    GST_DEBUG_OBJECT (self, "Bottom fields");

  if ((self->field_history[self->cur_field_idx].flags == PICTURE_INTERLACED_TOP
          && (self->fields == GST_DEINTERLACE_TF
              || IS_TELECINE (interlacing_mode)))
      || (self->fields == GST_DEINTERLACE_ALL
          && !IS_TELECINE (interlacing_mode))) {
    GST_DEBUG_OBJECT (self, "deinterlacing top field");

    /* create new buffer */
    ret = gst_buffer_pool_acquire_buffer (self->pool, &outbuf, NULL);
    if (ret != GST_FLOW_OK)
      goto no_buffer;

    g_return_val_if_fail (self->history_count >=
        1 + gst_deinterlace_method_get_latency (self->method), GST_FLOW_ERROR);

    buf =
        self->field_history[self->history_count - 1 -
        gst_deinterlace_method_get_latency (self->method)].frame->buffer;

    if (!IS_TELECINE (interlacing_mode)) {
      timestamp = GST_BUFFER_TIMESTAMP (buf);

      GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
      if (self->fields == GST_DEINTERLACE_ALL)
        GST_BUFFER_DURATION (outbuf) = self->field_duration;
      else
        GST_BUFFER_DURATION (outbuf) = 2 * self->field_duration;
      GST_DEBUG_OBJECT (self,
          "[ADJUST] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
          GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
          GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
          GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf) +
              GST_BUFFER_DURATION (outbuf)));
    } else {
      GST_BUFFER_TIMESTAMP (outbuf) =
          GST_BUFFER_TIMESTAMP (field1->frame->buffer);
      GST_BUFFER_DURATION (outbuf) =
          GST_BUFFER_DURATION (field1->frame->buffer);
    }

    /* Check if we need to drop the frame because of QoS */
    if (!gst_deinterlace_do_qos (self, buf)) {
      self->cur_field_idx--;
      gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
      gst_buffer_unref (outbuf);
      outbuf = NULL;
      ret = GST_FLOW_OK;
    } else {
      if (self->cur_field_idx < 0 && flushing) {
        if (self->history_count == 1) {
          gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
          goto need_more;
        }
        self->cur_field_idx++;
      }
      if (self->cur_field_idx < 0) {
        goto need_more;
      }
      if (!flushing && self->cur_field_idx < 1) {
        goto need_more;
      }

      /* map the frame so the deinterlace methods can write the data to the
       * correct memory locations */
      outframe =
          gst_video_frame_new_and_map (&self->vinfo, outbuf, GST_MAP_WRITE);

      /* do magic calculus */
      gst_deinterlace_method_deinterlace_frame (self->method,
          self->field_history, self->history_count, outframe,
          self->cur_field_idx);

      gst_video_frame_unmap_and_free (outframe);

      self->cur_field_idx--;
      /* need to remove the field in the telecine weaving case */
      if ((IS_TELECINE (interlacing_mode)
              && self->method_id == GST_DEINTERLACE_WEAVE)
          || self->cur_field_idx + 1 +
          gst_deinterlace_method_get_latency (self->method) <
          self->history_count || flushing) {
        gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
      }

      if (gst_deinterlace_clip_buffer (self, outbuf)) {
        GST_DEBUG_OBJECT (self,
            "[OUT] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
            GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
            GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
            GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf) +
                GST_BUFFER_DURATION (outbuf)));
        ret = gst_pad_push (self->srcpad, outbuf);
      } else {
        ret = GST_FLOW_OK;
        gst_buffer_unref (outbuf);
      }

      outbuf = NULL;
      if (ret != GST_FLOW_OK)
        return ret;
      if (IS_TELECINE (interlacing_mode)
          && self->method_id == GST_DEINTERLACE_WEAVE) {
        /* pop off the second field */
        GST_DEBUG_OBJECT (self, "Removing unused field (count: %d)",
            self->history_count);
        self->cur_field_idx--;
        gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
        interlacing_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
        return ret;
      }
    }

    if (flush_one && !self->drop_orphans) {
      GST_DEBUG_OBJECT (self, "Orphan field deinterlaced - reconfiguring");
      goto restart;
    }
  }
  /* no calculation done: remove excess field */
  else if (self->field_history[self->cur_field_idx].flags ==
      PICTURE_INTERLACED_TOP && (self->fields == GST_DEINTERLACE_BF
          && !IS_TELECINE (interlacing_mode))) {
    GST_DEBUG_OBJECT (self, "Removing unused top field");
    self->cur_field_idx--;
    gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));

    if (flush_one && !self->drop_orphans) {
      GST_DEBUG_OBJECT (self, "Orphan field deinterlaced - reconfiguring");
      goto restart;
    }
  }

  if (self->history_count < fields_required)
    return ret;

  if (self->cur_field_idx < 0)
    return ret;

  /* deinterlace bottom_field */
  if ((self->field_history[self->cur_field_idx].flags ==
          PICTURE_INTERLACED_BOTTOM && (self->fields == GST_DEINTERLACE_BF
              || IS_TELECINE (interlacing_mode)))
      || (self->fields == GST_DEINTERLACE_ALL
          && !IS_TELECINE (interlacing_mode))) {
    GST_DEBUG_OBJECT (self, "deinterlacing bottom field");

    /* create new buffer */
    ret = gst_buffer_pool_acquire_buffer (self->pool, &outbuf, NULL);
    if (ret != GST_FLOW_OK)
      goto no_buffer;

    g_return_val_if_fail (self->history_count >=
        gst_deinterlace_method_get_latency (self->method) + 1, GST_FLOW_ERROR);

    buf =
        self->field_history[self->history_count - 1 -
        gst_deinterlace_method_get_latency (self->method)].frame->buffer;
    if (!IS_TELECINE (interlacing_mode)) {
      timestamp = GST_BUFFER_TIMESTAMP (buf);

      if (self->fields == GST_DEINTERLACE_ALL) {
        GST_BUFFER_TIMESTAMP (outbuf) = timestamp + self->field_duration;
        GST_BUFFER_DURATION (outbuf) = self->field_duration;
      } else {
        GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
        GST_BUFFER_DURATION (outbuf) = 2 * self->field_duration;
      }
      GST_DEBUG_OBJECT (self,
          "[ADJUST] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
          GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
          GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
          GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf) +
              GST_BUFFER_DURATION (outbuf)));
    } else {
      GST_BUFFER_TIMESTAMP (outbuf) =
          GST_BUFFER_TIMESTAMP (field1->frame->buffer);
      GST_BUFFER_DURATION (outbuf) =
          GST_BUFFER_DURATION (field1->frame->buffer);
    }

    /* Check if we need to drop the frame because of QoS */
    if (!gst_deinterlace_do_qos (self, buf)) {
      self->cur_field_idx--;
      gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
      gst_buffer_unref (outbuf);
      outbuf = NULL;
      ret = GST_FLOW_OK;
    } else {
      /* map the frame so the deinterlace methods can write the data to the
       * correct memory locations */
      outframe =
          gst_video_frame_new_and_map (&self->vinfo, outbuf, GST_MAP_WRITE);

      /* do magic calculus */
      gst_deinterlace_method_deinterlace_frame (self->method,
          self->field_history, self->history_count, outframe,
          self->cur_field_idx);

      gst_video_frame_unmap_and_free (outframe);

      self->cur_field_idx--;
      /* need to remove the field in the telecine weaving case */
      if ((IS_TELECINE (interlacing_mode)
              && self->method_id == GST_DEINTERLACE_WEAVE)
          || self->cur_field_idx + 1 +
          gst_deinterlace_method_get_latency (self->method) <
          self->history_count) {
        gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
      }

      if (gst_deinterlace_clip_buffer (self, outbuf)) {
        GST_DEBUG_OBJECT (self,
            "[OUT] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
            GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
            GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
            GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf) +
                GST_BUFFER_DURATION (outbuf)));
        ret = gst_pad_push (self->srcpad, outbuf);
      } else {
        ret = GST_FLOW_OK;
        gst_buffer_unref (outbuf);
      }

      outbuf = NULL;
      if (ret != GST_FLOW_OK)
        return ret;
      if (IS_TELECINE (interlacing_mode)
          && self->method_id == GST_DEINTERLACE_WEAVE) {
        /* pop off the second field */
        GST_DEBUG_OBJECT (self, "Removing unused field (count: %d)",
            self->history_count);
        self->cur_field_idx--;
        gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
        interlacing_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
        return ret;
      }
    }

    if (flush_one && !self->drop_orphans) {
      GST_DEBUG_OBJECT (self, "Orphan field deinterlaced - reconfiguring");
      goto restart;
    }
  }
  /* no calculation done: remove excess field */
  else if (self->field_history[self->cur_field_idx].flags ==
      PICTURE_INTERLACED_BOTTOM && (self->fields == GST_DEINTERLACE_TF
          && !IS_TELECINE (interlacing_mode))) {
    GST_DEBUG_OBJECT (self, "Removing unused bottom field");
    self->cur_field_idx--;
    gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));

    if (flush_one && !self->drop_orphans) {
      GST_DEBUG_OBJECT (self, "Orphan field deinterlaced - reconfiguring");
      goto restart;
    }
  }

  return ret;

need_more:
  {
    self->need_more = TRUE;
    return ret;
  }
no_buffer:
  {
    GST_DEBUG_OBJECT (self, "could not allocate buffer");
    return ret;
  }
}

static gboolean
gst_deinterlace_get_latency (GstDeinterlace * self)
{
  if (self->locking == GST_DEINTERLACE_LOCKING_AUTO) {
    GstQuery *query;

    query = gst_query_new_latency ();
    if ((gst_pad_peer_query (self->sinkpad, query))) {
      gboolean is_live;
      /* if upstream is live, we use low-latency passive locking mode
       * else high-latency active locking mode */
      gst_query_parse_latency (query, &is_live, NULL, NULL);
      GST_DEBUG_OBJECT (self, "Latency query indicates stream is %s",
          is_live ? "live - using passive locking" :
          "not live - using active locking");
      gst_query_unref (query);
      return is_live;
    } else {
      /* conservatively use passive locking if the query fails */
      GST_WARNING_OBJECT (self,
          "Latency query failed - fall back to using passive locking");
      gst_query_unref (query);
      return TRUE;
    }
  } else {
    return self->locking - 2;
  }
}

static GstFlowReturn
gst_deinterlace_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstDeinterlace *self = GST_DEINTERLACE (parent);
  GstFlowReturn ret = GST_FLOW_OK;

  GST_OBJECT_LOCK (self);
  if (self->reconfigure || gst_pad_check_reconfigure (self->srcpad)) {
    GstCaps *caps;

    if ((gint) self->new_fields != -1)
      self->fields = self->new_fields;
    if ((gint) self->new_mode != -1)
      self->mode = self->new_mode;
    self->new_mode = -1;
    self->new_fields = -1;

    self->reconfigure = FALSE;
    GST_OBJECT_UNLOCK (self);
    caps = gst_pad_get_current_caps (self->sinkpad);
    if (caps != NULL) {
      if (!gst_deinterlace_setcaps (self, self->sinkpad, caps)) {
        gst_caps_unref (caps);
        return GST_FLOW_NOT_NEGOTIATED;
      }
      gst_caps_unref (caps);
    } else {
      return GST_FLOW_FLUSHING;
    }
  } else {
    GST_OBJECT_UNLOCK (self);
  }

  GST_DEBUG_OBJECT (self,
      "[IN] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
      GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf)));

  if (self->still_frame_mode || self->passthrough) {
    GST_DEBUG_OBJECT (self,
        "Frame type: Progressive?; pushing buffer using pass-through");
    GST_DEBUG_OBJECT (self,
        "[OUT] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
        GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf)));

    return gst_pad_push (self->srcpad, buf);
  }

  if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
    GST_DEBUG_OBJECT (self, "DISCONT buffer, resetting history");
    gst_deinterlace_reset_history (self, FALSE);
  }

  gst_deinterlace_push_history (self, buf);
  buf = NULL;

  do {
    ret = gst_deinterlace_output_frame (self, FALSE);
  } while (!self->need_more && self->history_count > 0 && ret == GST_FLOW_OK);

  return ret;
}

static gboolean
gst_deinterlace_acceptcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps)
{
  gboolean ret;
  GstCaps *ourcaps;

  /* In AUTO/DISABLED mode we accept everything that is compatible with
   * our template caps. In INTERLACED mode we force deinterlacing, meaning
   * we can only possibly support the deinterlace caps.
   * In AUTO_STRICT mode we accept all progressive formats, but only those
   * interlaced format that we can actually deinterlace */
  if (self->mode == GST_DEINTERLACE_MODE_DISABLED
      || self->mode == GST_DEINTERLACE_MODE_AUTO) {
    ourcaps = gst_pad_get_pad_template_caps (pad);
    ret = gst_caps_is_subset (caps, ourcaps);
    gst_caps_unref (ourcaps);
  } else if (self->mode == GST_DEINTERLACE_MODE_INTERLACED) {
    ourcaps = gst_static_caps_get (&deinterlace_caps);
    ret = gst_caps_is_subset (caps, ourcaps);
    gst_caps_unref (ourcaps);
  } else if (self->mode == GST_DEINTERLACE_MODE_AUTO_STRICT) {
    ourcaps = gst_static_caps_get (&progressive_caps);
    ret = gst_caps_is_subset (caps, ourcaps);
    gst_caps_unref (ourcaps);

    if (!ret) {
      ourcaps = gst_static_caps_get (&deinterlace_caps);
      ret = gst_caps_is_subset (caps, ourcaps);
      gst_caps_unref (ourcaps);
    }
  } else {
    g_assert_not_reached ();
  }

  GST_DEBUG_OBJECT (pad, "accept-caps result:%d for caps %" GST_PTR_FORMAT,
      ret, caps);

  return ret;
}

static gboolean
gst_deinterlace_fraction_double (gint * n_out, gint * d_out, gboolean half)
{
  gint n, d, gcd;

  n = *n_out;
  d = *d_out;

  if (d == 0)
    return FALSE;

  if (n == 0)
    return TRUE;

  gcd = gst_util_greatest_common_divisor (n, d);
  n /= gcd;
  d /= gcd;

  if (half) {
    if (G_MAXINT / 2 >= ABS (d)) {
      d *= 2;
    } else if (n >= 2 && n != G_MAXINT) {
      n /= 2;
    } else {
      d = G_MAXINT;
    }
  } else {
    if (G_MAXINT / 2 >= ABS (n)) {
      n *= 2;
    } else if (d >= 2 && d != G_MAXINT) {
      d /= 2;
    } else {
      n = G_MAXINT;
    }
  }

  *n_out = n;
  *d_out = d;

  return TRUE;
}

static GstCaps *
gst_deinterlace_caps_double_framerate (GstCaps * caps, gboolean half)
{
  guint len;

  for (len = gst_caps_get_size (caps); len > 0; len--) {
    GstStructure *s = gst_caps_get_structure (caps, len - 1);
    const GValue *val;

    val = gst_structure_get_value (s, "framerate");
    if (!val)
      continue;

    if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION) {
      gint n, d;

      n = gst_value_get_fraction_numerator (val);
      d = gst_value_get_fraction_denominator (val);

      if (!gst_deinterlace_fraction_double (&n, &d, half)) {
        gst_caps_remove_structure (caps, len - 1);
        continue;
      }

      gst_structure_set (s, "framerate", GST_TYPE_FRACTION, n, d, NULL);
    } else if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION_RANGE) {
      const GValue *min, *max;
      GValue nrange = { 0, }, nmin = {
      0,}, nmax = {
      0,};
      gint n, d;

      g_value_init (&nrange, GST_TYPE_FRACTION_RANGE);
      g_value_init (&nmin, GST_TYPE_FRACTION);
      g_value_init (&nmax, GST_TYPE_FRACTION);

      min = gst_value_get_fraction_range_min (val);
      max = gst_value_get_fraction_range_max (val);

      n = gst_value_get_fraction_numerator (min);
      d = gst_value_get_fraction_denominator (min);

      if (!gst_deinterlace_fraction_double (&n, &d, half)) {
        g_value_unset (&nrange);
        g_value_unset (&nmax);
        g_value_unset (&nmin);
        gst_caps_remove_structure (caps, len - 1);
        continue;
      }

      gst_value_set_fraction (&nmin, n, d);

      n = gst_value_get_fraction_numerator (max);
      d = gst_value_get_fraction_denominator (max);

      if (!gst_deinterlace_fraction_double (&n, &d, half)) {
        g_value_unset (&nrange);
        g_value_unset (&nmax);
        g_value_unset (&nmin);
        gst_caps_remove_structure (caps, len - 1);
        continue;
      }

      gst_value_set_fraction (&nmax, n, d);
      gst_value_set_fraction_range (&nrange, &nmin, &nmax);

      gst_structure_take_value (s, "framerate", &nrange);

      g_value_unset (&nmin);
      g_value_unset (&nmax);
    } else if (G_VALUE_TYPE (val) == GST_TYPE_LIST) {
      const GValue *lval;
      GValue nlist = { 0, };
      GValue nval = { 0, };
      gint i;

      g_value_init (&nlist, GST_TYPE_LIST);
      for (i = gst_value_list_get_size (val); i > 0; i--) {
        gint n, d;

        lval = gst_value_list_get_value (val, i - 1);

        if (G_VALUE_TYPE (lval) != GST_TYPE_FRACTION)
          continue;

        n = gst_value_get_fraction_numerator (lval);
        d = gst_value_get_fraction_denominator (lval);

        /* Double/Half the framerate but if this fails simply
         * skip this value from the list */
        if (!gst_deinterlace_fraction_double (&n, &d, half)) {
          continue;
        }

        g_value_init (&nval, GST_TYPE_FRACTION);

        gst_value_set_fraction (&nval, n, d);
        gst_value_list_append_and_take_value (&nlist, &nval);
      }
      gst_structure_take_value (s, "framerate", &nlist);
    }
  }

  return caps;
}

static GstCaps *
gst_deinterlace_getcaps (GstDeinterlace * self, GstPad * pad, GstCaps * filter)
{
  GstCaps *ret, *caps;
  GstPad *otherpad;
  gint len;
  GstCaps *ourcaps;
  GstCaps *peercaps;
  GstCaps *tmp, *tmp2;

  otherpad = (pad == self->srcpad) ? self->sinkpad : self->srcpad;

  ourcaps = gst_pad_get_pad_template_caps (pad);
  peercaps = gst_pad_peer_query_caps (otherpad, NULL);

  /* Filter any peercaps that are available with our template
   * to get started with the subset of caps we actually support */
  if (peercaps) {
    GST_DEBUG_OBJECT (pad, "Peer has caps %" GST_PTR_FORMAT, peercaps);
    caps = gst_caps_make_writable (gst_caps_intersect (ourcaps, peercaps));
    gst_caps_unref (peercaps);
    gst_caps_unref (ourcaps);
    peercaps = ourcaps = NULL;
  } else {
    caps = gst_caps_make_writable (ourcaps);
    ourcaps = NULL;
  }

  GST_DEBUG_OBJECT (pad,
      "Transforming caps %" GST_PTR_FORMAT " with filter %" GST_PTR_FORMAT,
      caps, filter);

  /* If deinterlacing is disabled, we just passthrough the
   * caps and everything */
  if (self->mode == GST_DEINTERLACE_MODE_DISABLED) {
    ret = caps;
    caps = NULL;
    goto done;
  }

  /* If deinterlacing is enforced, we can only accept the
   * caps for which we can actually do deinterlacing */
  if (self->mode == GST_DEINTERLACE_MODE_INTERLACED) {
    tmp = gst_static_caps_get (&deinterlace_caps);
    ret = gst_caps_intersect_full (caps, tmp, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (tmp);
    tmp = NULL;
    gst_caps_unref (caps);
    caps = NULL;
    goto done;
  }

  g_assert (self->mode == GST_DEINTERLACE_MODE_AUTO
      || self->mode == GST_DEINTERLACE_MODE_AUTO_STRICT);

  /* For the auto mode we have to do a bit more than that */
  ret = gst_caps_new_empty ();

  /* We can accept any structure if
   * - they are progressive already
   *
   */
  tmp = gst_static_caps_get (&progressive_caps);
  tmp2 = gst_caps_intersect_full (caps, tmp, GST_CAPS_INTERSECT_FIRST);
  gst_caps_unref (tmp);
  tmp = NULL;
  ret = gst_caps_merge (ret, tmp2);
  tmp2 = NULL;

  /* or
   * - they have sysmem caps features and a format for which we support
   *   deinterlacing
   * or
   * - they have ANY caps features, in which case we support it for
   *   sysmem caps features for formats we support
   *
   * NOTE: These are the caps where we actually would do deinterlacing
   * ourselves. If fields == ALL we would double the framerate so would
   * have to half the framerate constraints from downstream here
   */
  tmp = gst_static_caps_get (&deinterlace_caps);
  tmp2 = gst_caps_intersect_full (caps, tmp, GST_CAPS_INTERSECT_FIRST);
  gst_caps_unref (tmp);
  tmp = NULL;

  for (len = gst_caps_get_size (caps); len > 0; len--) {
    GstStructure *s = gst_caps_get_structure (caps, len - 1);

    if (pad == self->sinkpad)
      gst_structure_remove_field (s, "interlace-mode");
    else
      gst_structure_set (s, "interlace-mode", G_TYPE_STRING, "progressive",
          NULL);
  }

  if (self->fields == GST_DEINTERLACE_ALL) {
    tmp2 = gst_deinterlace_caps_double_framerate (tmp2, (pad == self->sinkpad));
  }

  ret = gst_caps_merge (ret, tmp2);
  tmp2 = NULL;

  /* or
   * - anything else in which case we would just passthrough again if we're
   *   only in AUTO and not AUTO_STRICT mode
   */
  if (self->mode == GST_DEINTERLACE_MODE_AUTO)
    ret = gst_caps_merge (ret, gst_caps_copy (caps));

  gst_caps_unref (caps);
  caps = NULL;

done:

  if (filter) {
    GstCaps *tmp;

    GST_LOG_OBJECT (pad, "intersecting with %" GST_PTR_FORMAT, filter);
    tmp = gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (ret);
    ret = tmp;
  }

  GST_DEBUG_OBJECT (pad, "Returning caps %" GST_PTR_FORMAT, ret);

  return ret;
}

/* takes ownership of the pool, allocator and query */
static gboolean
gst_deinterlace_set_allocation (GstDeinterlace * self,
    GstBufferPool * pool, GstAllocator * allocator,
    GstAllocationParams * params)
{
  GstAllocator *oldalloc;
  GstBufferPool *oldpool;

  GST_OBJECT_LOCK (self);
  oldpool = self->pool;
  self->pool = pool;

  oldalloc = self->allocator;
  self->allocator = allocator;

  if (params)
    self->params = *params;
  else
    gst_allocation_params_init (&self->params);
  GST_OBJECT_UNLOCK (self);

  if (oldpool) {
    GST_DEBUG_OBJECT (self, "deactivating old pool %p", oldpool);
    gst_buffer_pool_set_active (oldpool, FALSE);
    gst_object_unref (oldpool);
  }
  if (oldalloc) {
    gst_object_unref (oldalloc);
  }
  if (pool) {
    GST_DEBUG_OBJECT (self, "activating new pool %p", pool);
    gst_buffer_pool_set_active (pool, TRUE);
  }
  return TRUE;
}

static gboolean
gst_deinterlace_do_bufferpool (GstDeinterlace * self, GstCaps * outcaps)
{
  GstQuery *query;
  gboolean result = TRUE;
  GstBufferPool *pool;
  GstAllocator *allocator;
  GstAllocationParams params;
  GstStructure *config;
  guint size, min, max;

  if (self->passthrough) {
    /* we are in passthrough, the input buffer is never copied and always passed
     * along. We never allocate an output buffer on the srcpad. What we do is
     * let the upstream element decide if it wants to use a bufferpool and
     * then we will proxy the downstream pool */
    GST_DEBUG_OBJECT (self, "we're passthough, delay bufferpool");
    gst_deinterlace_set_allocation (self, NULL, NULL, NULL);
    return TRUE;
  }

  /* not passthrough, we need to allocate */
  /* find a pool for the negotiated caps now */
  GST_DEBUG_OBJECT (self, "doing allocation query");
  query = gst_query_new_allocation (outcaps, TRUE);
  if (!gst_pad_peer_query (self->srcpad, query)) {
    /* not a problem, just debug a little */
    GST_DEBUG_OBJECT (self, "peer ALLOCATION query failed");
  }

  GST_DEBUG_OBJECT (self, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, result,
      query);

  /* 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, &size, &min, &max);
  else {
    pool = NULL;
    size = GST_VIDEO_INFO_SIZE (&self->vinfo);
    min =
        MAX ((gst_deinterlace_method_get_fields_required (self->method) +
            1) / 2 + 1, 4);
    max = 0;
  }

  if (pool == NULL) {
    /* no pool, we can make our own */
    GST_DEBUG_OBJECT (self, "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_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
  gst_buffer_pool_set_config (pool, config);

  /* now store */
  result = gst_deinterlace_set_allocation (self, pool, allocator, &params);

  gst_query_unref (query);

  return result;
}


static gboolean
gst_deinterlace_setcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps)
{
  GstCaps *srccaps = NULL;
  GstVideoInterlaceMode interlacing_mode;
  gint fps_n, fps_d;

  gst_pad_check_reconfigure (self->srcpad);

  if (self->locking != GST_DEINTERLACE_LOCKING_NONE) {
    if (self->low_latency == -1)
      self->low_latency = gst_deinterlace_get_latency (self);

    if (self->pattern_lock) {
      /* refresh has been successful - we have a lock now */
      self->pattern_refresh = FALSE;
    } else {
      /* if we were not refreshing (!pattern_refresh) the caps have changed
       * so we need to refresh and we don't have a lock anymore
       * otherwise we have pattern_fresh and !pattern_lock anyway */
      self->pattern_refresh = TRUE;
      self->pattern_lock = FALSE;
    }
  }

  if (!gst_video_info_from_caps (&self->vinfo, caps))
    goto invalid_caps;

  fps_n = GST_VIDEO_INFO_FPS_N (&self->vinfo);
  fps_d = GST_VIDEO_INFO_FPS_D (&self->vinfo);

  /* Update passthrough information */
  if (self->mode == GST_DEINTERLACE_MODE_DISABLED) {
    self->passthrough = TRUE;
    GST_DEBUG_OBJECT (self, "Passthrough because mode=disabled");
  } else if (self->mode == GST_DEINTERLACE_MODE_INTERLACED) {
    GstCaps *tmp = gst_static_caps_get (&deinterlace_caps);

    if (!gst_caps_can_intersect (caps, tmp)) {
      gst_caps_unref (tmp);
      GST_ERROR_OBJECT (self, "Unsupported caps for mode=interlaced");
      goto invalid_caps;
    }

    self->passthrough = FALSE;
    GST_DEBUG_OBJECT (self, "Not passthrough because mode=interlaced");
  } else if (self->mode == GST_DEINTERLACE_MODE_AUTO
      || self->mode == GST_DEINTERLACE_MODE_AUTO_STRICT) {
    GstCaps *tmp = gst_static_caps_get (&deinterlace_caps);

    /* Already progressive? Passthrough */
    if (!GST_VIDEO_INFO_IS_INTERLACED (&self->vinfo)) {
      GST_DEBUG_OBJECT (self,
          "Passthrough because mode=auto and progressive caps");
      self->passthrough = TRUE;
    } else if (gst_caps_can_intersect (caps, tmp)) {
      GstCaps *peercaps;

      peercaps = gst_pad_peer_query_caps (self->srcpad, NULL);
      if (peercaps) {
        GstCaps *templcaps = gst_pad_get_pad_template_caps (self->srcpad);
        GstCaps *allowed_caps;
        GstCaps *tmp2;
        GstStructure *s;

        allowed_caps = gst_caps_intersect (templcaps, peercaps);
        gst_caps_unref (templcaps);
        gst_caps_unref (peercaps);
        peercaps = allowed_caps;
        allowed_caps = gst_caps_intersect (peercaps, tmp);
        gst_caps_unref (peercaps);

        tmp2 = gst_caps_copy (caps);
        s = gst_caps_get_structure (tmp2, 0);
        gst_structure_set (s, "interlace-mode", G_TYPE_STRING, "progressive",
            NULL);
        gst_structure_remove_field (s, "framerate");

        /* Downstream does not support progressive caps but supports
         * the upstream caps, go passthrough.
         * TODO: We might want to check the framerate compatibility
         * of the caps too here
         */
        if (gst_caps_can_intersect (allowed_caps, caps)
            && !gst_caps_can_intersect (allowed_caps, tmp2)) {
          GST_DEBUG_OBJECT (self,
              "Passthrough because mode=auto, "
              "downstream does not support progressive caps and interlaced caps");
          self->passthrough = TRUE;
        } else {
          GST_DEBUG_OBJECT (self, "Not passthrough because mode=auto, "
              "downstream supports progressive caps and interlaced caps");
          self->passthrough = FALSE;
        }

        gst_caps_unref (allowed_caps);
        gst_caps_unref (tmp2);
      } else {
        GST_DEBUG_OBJECT (self,
            "Not passthrough because mode=auto and interlaced caps");
        self->passthrough = FALSE;
      }
    } else {
      if (self->mode == GST_DEINTERLACE_MODE_AUTO) {
        GST_WARNING_OBJECT (self,
            "Passthrough because mode=auto and unsupported interlaced caps");
        self->passthrough = TRUE;
      } else {
        gst_caps_unref (tmp);
        GST_ERROR_OBJECT (self,
            "Unsupported interlaced caps in mode=auto-strict");
        goto invalid_caps;
      }
    }

    gst_caps_unref (tmp);
  } else {
    g_assert_not_reached ();
  }

  interlacing_mode = GST_VIDEO_INFO_INTERLACE_MODE (&self->vinfo);

  if (!self->passthrough) {
    if (self->pattern_lock) {
      srccaps = gst_caps_copy (caps);
      if (self->pattern != -1
          && G_UNLIKELY (!gst_util_fraction_multiply (fps_n, fps_d,
                  telecine_patterns[self->pattern].ratio_n,
                  telecine_patterns[self->pattern].ratio_d, &fps_n, &fps_d)))
        GST_ERROR_OBJECT (self,
            "Multiplying the framerate by the telecine pattern ratio overflowed!");
      gst_caps_set_simple (srccaps, "framerate", GST_TYPE_FRACTION, fps_n,
          fps_d, NULL);
    } else if (self->locking == GST_DEINTERLACE_LOCKING_ACTIVE
        || self->low_latency == 0) {
      /* in high latency pattern locking mode if we don't have a pattern lock,
       * the sink pad caps are the best we know */
      srccaps = gst_caps_copy (caps);
    } else if (self->low_latency > 0
        && interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED
        && self->pattern == -1) {
      /* for initial buffers of a telecine pattern, until there is a lock we
       * we output naïvely adjusted timestamps in low-latency pattern locking
       * mode */
      srccaps = gst_caps_copy (caps);
      gst_caps_set_simple (srccaps, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
    } else if (self->fields == GST_DEINTERLACE_ALL) {
      if (!gst_deinterlace_fraction_double (&fps_n, &fps_d, FALSE))
        goto invalid_caps;

      srccaps = gst_caps_copy (caps);

      gst_caps_set_simple (srccaps, "framerate", GST_TYPE_FRACTION, fps_n,
          fps_d, NULL);
    } else {
      srccaps = gst_caps_copy (caps);
    }

    /* If not passthrough, we are going to output progressive content */
    srccaps = gst_caps_make_writable (srccaps);
    gst_caps_set_simple (srccaps, "interlace-mode", G_TYPE_STRING,
        "progressive", NULL);

    gst_deinterlace_set_method (self, self->method_id);
    gst_deinterlace_method_setup (self->method, &self->vinfo);
  } else {
    srccaps = gst_caps_ref (caps);
  }

  if (fps_n != 0) {
    self->field_duration = gst_util_uint64_scale (GST_SECOND, fps_d, fps_n);
  } else {
    self->field_duration = 0;
  }

  GST_DEBUG_OBJECT (pad, "Sink caps: %" GST_PTR_FORMAT, caps);
  GST_DEBUG_OBJECT (pad, "Src  caps: %" GST_PTR_FORMAT, srccaps);

  if (!gst_pad_set_caps (self->srcpad, srccaps))
    goto set_caps_failed;

  if (!gst_deinterlace_do_bufferpool (self, srccaps))
    goto no_bufferpool;

  gst_caps_unref (srccaps);

  return TRUE;

invalid_caps:
  {
    GST_ERROR_OBJECT (pad, "Invalid caps: %" GST_PTR_FORMAT, caps);
    return FALSE;
  }
set_caps_failed:
  {
    GST_ERROR_OBJECT (pad, "Failed to set caps: %" GST_PTR_FORMAT, srccaps);
    if (srccaps)
      gst_caps_unref (srccaps);
    return FALSE;
  }
no_bufferpool:
  {
    GST_ERROR_OBJECT (pad, "could not negotiate bufferpool");
    if (srccaps)
      gst_caps_unref (srccaps);
    return FALSE;
  }
}

static gboolean
gst_deinterlace_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  GstDeinterlace *self = GST_DEINTERLACE (parent);

  GST_LOG_OBJECT (pad, "received %s event: %" GST_PTR_FORMAT,
      GST_EVENT_TYPE_NAME (event), event);

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

      gst_event_parse_caps (event, &caps);
      res = gst_deinterlace_setcaps (self, pad, caps);
      gst_event_unref (event);
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      const GstSegment *segment;

      gst_event_parse_segment (event, &segment);

      gst_deinterlace_reset_qos (self);
      gst_deinterlace_reset_history (self, FALSE);

      if (segment->format == GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (pad,
            "Got SEGMENT event in TIME format, passing on (%"
            GST_TIME_FORMAT " - %" GST_TIME_FORMAT ")",
            GST_TIME_ARGS (segment->start), GST_TIME_ARGS (segment->stop));
        gst_segment_copy_into (segment, &self->segment);
      } else {
        GST_WARNING_OBJECT (pad, "Got SEGMENT event in %s format",
            gst_format_get_name (segment->format));
        gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
      }

      res = gst_pad_push_event (self->srcpad, event);
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:{
      gboolean still_state;

      if (gst_video_event_parse_still_frame (event, &still_state)) {
        GST_DEBUG_OBJECT (self, "Received still frame event, state %d",
            still_state);

        if (still_state) {
          GstFlowReturn ret;

          GST_DEBUG_OBJECT (self, "Handling still frame");
          self->still_frame_mode = TRUE;
          gst_deinterlace_reset_history (self, FALSE);
          if (self->last_buffer) {
            ret =
                gst_pad_push (self->srcpad, gst_buffer_ref (self->last_buffer));
            GST_DEBUG_OBJECT (self, "Pushed still frame, result: %s",
                gst_flow_get_name (ret));
          } else {
            GST_WARNING_OBJECT (self, "No pending buffer!");
          }
        } else {
          GST_DEBUG_OBJECT (self, "Ending still frames");
          self->still_frame_mode = FALSE;
        }
      }

      res = gst_pad_push_event (self->srcpad, event);
      break;
    }
    case GST_EVENT_EOS:
      self->have_eos = TRUE;
      gst_deinterlace_reset_history (self, FALSE);
      res = gst_pad_push_event (self->srcpad, event);
      break;

    case GST_EVENT_FLUSH_STOP:
      if (self->still_frame_mode) {
        GST_DEBUG_OBJECT (self, "Ending still frames");
        self->still_frame_mode = FALSE;
      }
      gst_deinterlace_reset_qos (self);
      res = gst_pad_push_event (self->srcpad, event);
      gst_deinterlace_reset_history (self, TRUE);
      break;

    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

  return res;
}

static gboolean
gst_deinterlace_propose_allocation (GstDeinterlace * self, GstQuery * query)
{
  GstBufferPool *pool;
  GstCaps *caps;
  GstVideoInfo info;
  guint size;
  GstStructure *config;

  gst_query_parse_allocation (query, &caps, NULL);

  if (caps == NULL)
    return FALSE;

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

  size = GST_VIDEO_INFO_SIZE (&info);

  pool = gst_video_buffer_pool_new ();

  gst_query_add_allocation_pool (query, pool, size, 0, 0);

  config = gst_buffer_pool_get_config (pool);
  gst_buffer_pool_config_set_params (config, caps, size,
      (gst_deinterlace_method_get_fields_required (self->method) + 1) / 2 + 1,
      0);
  gst_buffer_pool_set_config (pool, config);

  gst_object_unref (pool);
  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);

  return TRUE;
}

static gboolean
gst_deinterlace_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstDeinterlace *self = GST_DEINTERLACE (parent);
  gboolean res = FALSE;

  GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query));

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

      gst_query_parse_caps (query, &filter);
      caps = gst_deinterlace_getcaps (self, pad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    case GST_QUERY_ACCEPT_CAPS:
    {
      GstCaps *caps;
      gboolean ret;

      gst_query_parse_accept_caps (query, &caps);
      ret = gst_deinterlace_acceptcaps (self, pad, caps);
      gst_query_set_accept_caps_result (query, ret);
      res = TRUE;
      break;
    }
    case GST_QUERY_ALLOCATION:
      if (self->passthrough)
        res = gst_pad_peer_query (self->srcpad, query);
      else
        res = gst_deinterlace_propose_allocation (self, query);
      break;
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
  return res;
}

static GstStateChangeReturn
gst_deinterlace_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstDeinterlace *self = GST_DEINTERLACE (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret != GST_STATE_CHANGE_SUCCESS)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_deinterlace_reset (self);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
    default:
      break;
  }

  return ret;
}

static gboolean
gst_deinterlace_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstDeinterlace *self = GST_DEINTERLACE (parent);
  gboolean res;

  GST_DEBUG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_QOS:{
      GstClockTimeDiff diff;
      GstClockTime timestamp;
      GstQOSType type;
      gdouble proportion;

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

      gst_deinterlace_update_qos (self, proportion, diff, timestamp);
    }
      /* fall through */
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

  return res;
}

static gboolean
gst_deinterlace_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstDeinterlace *self = GST_DEINTERLACE (parent);
  gboolean res = FALSE;

  GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:
      if (!self->passthrough) {
        GstClockTime min, max;
        gboolean live;
        GstPad *peer;

        if ((peer = gst_pad_get_peer (self->sinkpad))) {
          if ((res = gst_pad_query (peer, query))) {
            GstClockTime latency;
            gint fields_required = 0;
            gint method_latency = 0;

            if (self->method) {
              fields_required =
                  gst_deinterlace_method_get_fields_required (self->method);
              method_latency =
                  gst_deinterlace_method_get_latency (self->method);
            }

            gst_query_parse_latency (query, &live, &min, &max);

            GST_DEBUG_OBJECT (self, "Peer latency: min %"
                GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
                GST_TIME_ARGS (min), GST_TIME_ARGS (max));

            /* add our own latency */
            latency = (fields_required + method_latency) * self->field_duration;

            GST_DEBUG_OBJECT (self, "Our latency: min %" GST_TIME_FORMAT
                ", max %" GST_TIME_FORMAT,
                GST_TIME_ARGS (latency), GST_TIME_ARGS (latency));

            min += latency;
            if (max != GST_CLOCK_TIME_NONE)
              max += latency;

            GST_DEBUG_OBJECT (self, "Calculated total latency : min %"
                GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
                GST_TIME_ARGS (min), GST_TIME_ARGS (max));

            gst_query_set_latency (query, live, min, max);
          }
          gst_object_unref (peer);
        } else {
          res = FALSE;
        }
        break;
      }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

  return res;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (deinterlace_debug, "deinterlace", 0, "Deinterlacer");

#if HAVE_ORC
  orc_init ();
#endif

  if (!gst_element_register (plugin, "deinterlace", GST_RANK_NONE,
          GST_TYPE_DEINTERLACE)) {
    return FALSE;
  }

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    deinterlace,
    "Deinterlacer", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
    GST_PACKAGE_ORIGIN);
