/* GStreamer
 * Copyright (C) 2013 David Schleef <ds@schleef.org>
 * Copyright (C) 2013 Rdio Inc <ingestions@rdio.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Suite 500,
 * Boston, MA 02110-1335, USA.
 */
/**
 * SECTION:element-gstivtc
 *
 * The ivtc element is an inverse telecine filter.  It takes interlaced
 * video that was created from progressive content using a telecine
 * filter, and reconstructs the original progressive content.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v videotestsrc pattern=ball ! video/x-raw,framerate=24/1 !
 *     interlace !
 *     ivtc ! video/x-raw,framerate=24/1 ! fakesink
 * ]|
 *
 * This pipeline creates a progressive video stream at 24 fps, and
 * converts it to a 60 fields per second interlaced stream.  Then the
 * stream is inversed telecine'd back to 24 fps, yielding approximately
 * the original videotestsrc content.
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/video/video.h>
#include "gstivtc.h"
#include <string.h>
#include <math.h>

/* only because element registration is in this file */
#include "gstcombdetect.h"

GST_DEBUG_CATEGORY_STATIC (gst_ivtc_debug_category);
#define GST_CAT_DEFAULT gst_ivtc_debug_category

/* prototypes */


static GstCaps *gst_ivtc_transform_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter);
static GstCaps *gst_ivtc_fixate_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
static gboolean gst_ivtc_set_caps (GstBaseTransform * trans, GstCaps * incaps,
    GstCaps * outcaps);
static gboolean gst_ivtc_sink_event (GstBaseTransform * trans,
    GstEvent * event);
static GstFlowReturn gst_ivtc_transform (GstBaseTransform * trans,
    GstBuffer * inbuf, GstBuffer * outbuf);
static void gst_ivtc_flush (GstIvtc * ivtc);
static void gst_ivtc_retire_fields (GstIvtc * ivtc, int n_fields);
static void gst_ivtc_construct_frame (GstIvtc * itvc, GstBuffer * outbuf);

static int get_comb_score (GstVideoFrame * top, GstVideoFrame * bottom);

enum
{
  PROP_0
};

/* pad templates */

#define MAX_WIDTH 2048
#define VIDEO_CAPS \
  "video/x-raw, " \
  "format = (string) { I420, Y444, Y42B }, " \
  "width = [1, 2048], " \
  "height = " GST_VIDEO_SIZE_RANGE ", " \
  "framerate = " GST_VIDEO_FPS_RANGE

static GstStaticPadTemplate gst_ivtc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (VIDEO_CAPS)
    );

static GstStaticPadTemplate gst_ivtc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (VIDEO_CAPS)
    );


/* class initialization */

G_DEFINE_TYPE_WITH_CODE (GstIvtc, gst_ivtc, GST_TYPE_BASE_TRANSFORM,
    GST_DEBUG_CATEGORY_INIT (gst_ivtc_debug_category, "ivtc", 0,
        "debug category for ivtc element"));

static void
gst_ivtc_class_init (GstIvtcClass * klass)
{
  GstBaseTransformClass *base_transform_class =
      GST_BASE_TRANSFORM_CLASS (klass);

  /* Setting up pads and setting metadata should be moved to
     base_class_init if you intend to subclass this class. */
  gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
      &gst_ivtc_sink_template);
  gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
      &gst_ivtc_src_template);

  gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
      "Inverse Telecine", "Video/Filter", "Inverse Telecine Filter",
      "David Schleef <ds@schleef.org>");

  base_transform_class->transform_caps =
      GST_DEBUG_FUNCPTR (gst_ivtc_transform_caps);
  base_transform_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_ivtc_fixate_caps);
  base_transform_class->set_caps = GST_DEBUG_FUNCPTR (gst_ivtc_set_caps);
  base_transform_class->sink_event = GST_DEBUG_FUNCPTR (gst_ivtc_sink_event);
  base_transform_class->transform = GST_DEBUG_FUNCPTR (gst_ivtc_transform);
}

static void
gst_ivtc_init (GstIvtc * ivtc)
{
}

static GstCaps *
gst_ivtc_transform_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
  GstCaps *othercaps;
  int i;

  othercaps = gst_caps_copy (caps);

  if (direction == GST_PAD_SRC) {
    GValue value = G_VALUE_INIT;
    GValue v = G_VALUE_INIT;

    g_value_init (&value, GST_TYPE_LIST);
    g_value_init (&v, G_TYPE_STRING);

    g_value_set_string (&v, "interleaved");
    gst_value_list_append_value (&value, &v);
    g_value_set_string (&v, "mixed");
    gst_value_list_append_value (&value, &v);
    g_value_set_string (&v, "progressive");
    gst_value_list_append_value (&value, &v);

    for (i = 0; i < gst_caps_get_size (othercaps); i++) {
      GstStructure *structure = gst_caps_get_structure (othercaps, i);
      gst_structure_set_value (structure, "interlace-mode", &value);
      gst_structure_remove_field (structure, "framerate");
    }
    g_value_unset (&value);
    g_value_unset (&v);
  } else {
    for (i = 0; i < gst_caps_get_size (othercaps); i++) {
      GstStructure *structure = gst_caps_get_structure (othercaps, i);
      gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
          "progressive", NULL);
      gst_structure_remove_field (structure, "framerate");
    }
  }

  if (filter) {
    GstCaps *intersect;

    intersect = gst_caps_intersect (othercaps, filter);
    gst_caps_unref (othercaps);
    othercaps = intersect;
  }

  return othercaps;
}

static GstCaps *
gst_ivtc_fixate_caps (GstBaseTransform * trans, GstPadDirection direction,
    GstCaps * caps, GstCaps * othercaps)
{
  GstCaps *result;

  GST_DEBUG_OBJECT (trans, "fixating caps %" GST_PTR_FORMAT, othercaps);

  result = gst_caps_make_writable (othercaps);
  if (direction == GST_PAD_SINK) {
    GstVideoInfo info;
    if (gst_video_info_from_caps (&info, caps)) {
      /* Smarter decision */
      GST_DEBUG_OBJECT (trans, "Input framerate is %d/%d", info.fps_n,
          info.fps_d);
      if (info.fps_n == 30000 && info.fps_d == 1001)
        gst_caps_set_simple (result, "framerate", GST_TYPE_FRACTION, 24000,
            1001, NULL);
      else
        gst_caps_set_simple (result, "framerate", GST_TYPE_FRACTION, 24, 1,
            NULL);
    } else {
      gst_caps_set_simple (result, "framerate", GST_TYPE_FRACTION, 24, 1, NULL);
    }
  }

  result = gst_caps_fixate (result);

  return result;
}

static gboolean
gst_ivtc_set_caps (GstBaseTransform * trans, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstIvtc *ivtc = GST_IVTC (trans);

  gst_video_info_from_caps (&ivtc->sink_video_info, incaps);
  gst_video_info_from_caps (&ivtc->src_video_info, outcaps);

  ivtc->field_duration = gst_util_uint64_scale_int (GST_SECOND,
      ivtc->sink_video_info.fps_d, ivtc->sink_video_info.fps_n * 2);
  GST_DEBUG_OBJECT (trans, "field duration %" GST_TIME_FORMAT,
      GST_TIME_ARGS (ivtc->field_duration));

  return TRUE;
}

/* sink and src pad event handlers */
static gboolean
gst_ivtc_sink_event (GstBaseTransform * trans, GstEvent * event)
{
  GstIvtc *ivtc = GST_IVTC (trans);

  GST_DEBUG_OBJECT (ivtc, "sink_event");

  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
    const GstSegment *seg;

    gst_ivtc_flush (ivtc);

    /* FIXME this should handle update events */

    gst_event_parse_segment (event, &seg);
    gst_segment_copy_into (seg, &ivtc->segment);
    ivtc->current_ts = ivtc->segment.start;
  }

  return GST_BASE_TRANSFORM_CLASS (gst_ivtc_parent_class)->sink_event (trans,
      event);
}

static void
gst_ivtc_flush (GstIvtc * ivtc)
{
  if (ivtc->n_fields > 0) {
    GST_FIXME_OBJECT (ivtc, "not sending flushed fields to srcpad");
  }

  gst_ivtc_retire_fields (ivtc, ivtc->n_fields);
}

enum
{
  TOP_FIELD = 0,
  BOTTOM_FIELD = 1
};

static void
add_field (GstIvtc * ivtc, GstBuffer * buffer, int parity, int index)
{
  int i = ivtc->n_fields;
  GstClockTime ts;
  GstIvtcField *field = &ivtc->fields[i];

  g_return_if_fail (i < GST_IVTC_MAX_FIELDS);

  ts = GST_BUFFER_PTS (buffer) + index * ivtc->field_duration;
  if (ts + ivtc->field_duration < ivtc->segment.start) {
    /* drop, it's before our segment */
    return;
  }

  GST_DEBUG ("adding field %d", i);

  field->buffer = gst_buffer_ref (buffer);
  field->parity = parity;
  field->ts = ts;

  gst_video_frame_map (&ivtc->fields[i].frame, &ivtc->sink_video_info,
      buffer, GST_MAP_READ);

  ivtc->n_fields++;
}

static int
similarity (GstIvtc * ivtc, int i1, int i2)
{
  GstIvtcField *f1, *f2;
  int score;

  g_return_val_if_fail (i1 >= 0 && i1 < ivtc->n_fields, 0);
  g_return_val_if_fail (i2 >= 0 && i2 < ivtc->n_fields, 0);

  f1 = &ivtc->fields[i1];
  f2 = &ivtc->fields[i2];

  if (f1->parity == TOP_FIELD) {
    score = get_comb_score (&f1->frame, &f2->frame);
  } else {
    score = get_comb_score (&f2->frame, &f1->frame);
  }

  GST_DEBUG ("score %d", score);

  return score;
}

#define GET_LINE(frame,comp,line) (((unsigned char *)(frame)->data[k]) + \
      (line) * GST_VIDEO_FRAME_COMP_STRIDE((frame), (comp)))
#define GET_LINE_IL(top,bottom,comp,line) \
  (((unsigned char *)(((line)&1)?(bottom):(top))->data[k]) + \
      (line) * GST_VIDEO_FRAME_COMP_STRIDE((top), (comp)))

static void
reconstruct (GstIvtc * ivtc, GstVideoFrame * dest_frame, int i1, int i2)
{
  GstVideoFrame *top, *bottom;
  int width, height;
  int j, k;

  g_return_if_fail (i1 >= 0 && i1 < ivtc->n_fields);
  g_return_if_fail (i2 >= 0 && i2 < ivtc->n_fields);

  if (ivtc->fields[i1].parity == TOP_FIELD) {
    top = &ivtc->fields[i1].frame;
    bottom = &ivtc->fields[i2].frame;
  } else {
    bottom = &ivtc->fields[i1].frame;
    top = &ivtc->fields[i2].frame;
  }

  for (k = 0; k < 3; k++) {
    height = GST_VIDEO_FRAME_COMP_HEIGHT (top, k);
    width = GST_VIDEO_FRAME_COMP_WIDTH (top, k);
    for (j = 0; j < height; j++) {
      guint8 *dest = GET_LINE (dest_frame, k, j);
      guint8 *src = GET_LINE_IL (top, bottom, k, j);

      memcpy (dest, src, width);
    }
  }

}

static int
reconstruct_line (guint8 * line1, guint8 * line2, int i, int a, int b, int c,
    int d)
{
  int x;

  x = line1[i - 3] * a;
  x += line1[i - 2] * b;
  x += line1[i - 1] * c;
  x += line1[i - 0] * d;
  x += line2[i + 0] * d;
  x += line2[i + 1] * c;
  x += line2[i + 2] * b;
  x += line2[i + 3] * a;
  return (x + 16) >> 5;
}


static void
reconstruct_single (GstIvtc * ivtc, GstVideoFrame * dest_frame, int i1)
{
  int j;
  int k;
  int height;
  int width;
  GstIvtcField *field = &ivtc->fields[i1];

  for (k = 0; k < 1; k++) {
    height = GST_VIDEO_FRAME_COMP_HEIGHT (dest_frame, k);
    width = GST_VIDEO_FRAME_COMP_WIDTH (dest_frame, k);
    for (j = 0; j < height; j++) {
      if ((j & 1) == field->parity) {
        memcpy (GET_LINE (dest_frame, k, j),
            GET_LINE (&field->frame, k, j), width);
      } else {
        if (j == 0 || j == height - 1) {
          memcpy (GET_LINE (dest_frame, k, j),
              GET_LINE (&field->frame, k, (j ^ 1)), width);
        } else {
          guint8 *dest = GET_LINE (dest_frame, k, j);
          guint8 *line1 = GET_LINE (&field->frame, k, j - 1);
          guint8 *line2 = GET_LINE (&field->frame, k, j + 1);
          int i;

#define MARGIN 3
          for (i = MARGIN; i < width - MARGIN; i++) {
            int dx, dy;

            dx = -line1[i - 1] - line2[i - 1] + line1[i + 1] + line2[i + 1];
            dx *= 2;

            dy = -line1[i - 1] - 2 * line1[i] - line1[i + 1]
                + line2[i - 1] + 2 * line2[i] + line2[i + 1];
            if (dy < 0) {
              dy = -dy;
              dx = -dx;
            }

            if (dx == 0 && dy == 0) {
              dest[i] = (line1[i] + line2[i] + 1) >> 1;
            } else if (dx < 0) {
              if (dx < -2 * dy) {
                dest[i] = reconstruct_line (line1, line2, i, 0, 0, 0, 16);
              } else if (dx < -dy) {
                dest[i] = reconstruct_line (line1, line2, i, 0, 0, 8, 8);
              } else if (2 * dx < -dy) {
                dest[i] = reconstruct_line (line1, line2, i, 0, 4, 8, 4);
              } else if (3 * dx < -dy) {
                dest[i] = reconstruct_line (line1, line2, i, 1, 7, 7, 1);
              } else {
                dest[i] = reconstruct_line (line1, line2, i, 4, 8, 4, 0);
              }
            } else {
              if (dx > 2 * dy) {
                dest[i] = reconstruct_line (line2, line1, i, 0, 0, 0, 16);
              } else if (dx > dy) {
                dest[i] = reconstruct_line (line2, line1, i, 0, 0, 8, 8);
              } else if (2 * dx > dy) {
                dest[i] = reconstruct_line (line2, line1, i, 0, 4, 8, 4);
              } else if (3 * dx > dy) {
                dest[i] = reconstruct_line (line2, line1, i, 1, 7, 7, 1);
              } else {
                dest[i] = reconstruct_line (line2, line1, i, 4, 8, 4, 0);
              }
            }
          }

          for (i = 0; i < MARGIN; i++) {
            dest[i] = (line1[i] + line2[i] + 1) >> 1;
          }
          for (i = width - MARGIN; i < width; i++) {
            dest[i] = (line1[i] + line2[i] + 1) >> 1;
          }
        }
      }
    }
  }
  for (k = 1; k < 3; k++) {
    height = GST_VIDEO_FRAME_COMP_HEIGHT (dest_frame, k);
    width = GST_VIDEO_FRAME_COMP_WIDTH (dest_frame, k);
    for (j = 0; j < height; j++) {
      if ((j & 1) == field->parity) {
        memcpy (GET_LINE (dest_frame, k, j),
            GET_LINE (&field->frame, k, j), width);
      } else {
        if (j == 0 || j == height - 1) {
          memcpy (GET_LINE (dest_frame, k, j),
              GET_LINE (&field->frame, k, (j ^ 1)), width);
        } else {
          guint8 *dest = GET_LINE (dest_frame, k, j);
          guint8 *line1 = GET_LINE (&field->frame, k, j - 1);
          guint8 *line2 = GET_LINE (&field->frame, k, j + 1);
          int i;
          for (i = 0; i < width; i++) {
            dest[i] = (line1[i] + line2[i] + 1) >> 1;
          }
        }
      }
    }
  }
}

static void
gst_ivtc_retire_fields (GstIvtc * ivtc, int n_fields)
{
  int i;

  if (n_fields == 0)
    return;

  for (i = 0; i < n_fields; i++) {
    gst_video_frame_unmap (&ivtc->fields[i].frame);
    gst_buffer_unref (ivtc->fields[i].buffer);
  }

  memmove (ivtc->fields, ivtc->fields + n_fields,
      sizeof (GstIvtcField) * (ivtc->n_fields - n_fields));
  ivtc->n_fields -= n_fields;
}

static GstFlowReturn
gst_ivtc_transform (GstBaseTransform * trans, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  GstIvtc *ivtc = GST_IVTC (trans);
  GstFlowReturn ret;

  GST_DEBUG_OBJECT (ivtc, "transform");

  if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_VIDEO_BUFFER_FLAG_TFF)) {
    add_field (ivtc, inbuf, TOP_FIELD, 0);
    if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_VIDEO_BUFFER_FLAG_ONEFIELD)) {
      add_field (ivtc, inbuf, BOTTOM_FIELD, 1);
      if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_VIDEO_BUFFER_FLAG_RFF)) {
        add_field (ivtc, inbuf, TOP_FIELD, 2);
      }
    }
  } else {
    add_field (ivtc, inbuf, BOTTOM_FIELD, 0);
    if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_VIDEO_BUFFER_FLAG_ONEFIELD)) {
      add_field (ivtc, inbuf, TOP_FIELD, 1);
      if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_VIDEO_BUFFER_FLAG_RFF)) {
        add_field (ivtc, inbuf, BOTTOM_FIELD, 2);
      }
    }
  }

  while (ivtc->n_fields > 0 &&
      ivtc->fields[0].ts + GST_MSECOND * 50 < ivtc->current_ts) {
    GST_DEBUG ("retiring early field");
    gst_ivtc_retire_fields (ivtc, 1);
  }

  GST_DEBUG ("n_fields %d", ivtc->n_fields);
  if (ivtc->n_fields < 4) {
    return GST_BASE_TRANSFORM_FLOW_DROPPED;
  }

  gst_ivtc_construct_frame (ivtc, outbuf);
  while (ivtc->n_fields >= 4) {
    GstBuffer *buf;
    buf = gst_buffer_copy (outbuf);
    GST_DEBUG ("pushing extra frame");
    ret = gst_pad_push (GST_BASE_TRANSFORM_SRC_PAD (trans), buf);
    if (ret != GST_FLOW_OK) {
      return ret;
    }

    gst_ivtc_construct_frame (ivtc, outbuf);
  }

  return GST_FLOW_OK;
}

static void
gst_ivtc_construct_frame (GstIvtc * ivtc, GstBuffer * outbuf)
{
  int anchor_index;
  int prev_score, next_score;
  GstVideoFrame dest_frame;
  int n_retire;
  gboolean forward_ok;

  anchor_index = 1;
  if (ivtc->fields[anchor_index].ts < ivtc->current_ts) {
    forward_ok = TRUE;
  } else {
    forward_ok = FALSE;
  }

  prev_score = similarity (ivtc, anchor_index - 1, anchor_index);
  next_score = similarity (ivtc, anchor_index, anchor_index + 1);

  gst_video_frame_map (&dest_frame, &ivtc->src_video_info, outbuf,
      GST_MAP_WRITE);

#define THRESHOLD 100
  if (prev_score < THRESHOLD) {
    if (forward_ok && next_score < prev_score) {
      reconstruct (ivtc, &dest_frame, anchor_index, anchor_index + 1);
      n_retire = anchor_index + 2;
    } else {
      if (prev_score >= THRESHOLD / 2) {
        GST_INFO ("borderline prev (%d, %d)", prev_score, next_score);
      }
      reconstruct (ivtc, &dest_frame, anchor_index, anchor_index - 1);
      n_retire = anchor_index + 1;
    }
  } else if (next_score < THRESHOLD) {
    if (next_score >= THRESHOLD / 2) {
      GST_INFO ("borderline prev (%d, %d)", prev_score, next_score);
    }
    reconstruct (ivtc, &dest_frame, anchor_index, anchor_index + 1);
    if (forward_ok) {
      n_retire = anchor_index + 2;
    } else {
      n_retire = anchor_index + 1;
    }
  } else {
    if (prev_score < THRESHOLD * 2 || next_score < THRESHOLD * 2) {
      GST_INFO ("borderline single (%d, %d)", prev_score, next_score);
    }
    reconstruct_single (ivtc, &dest_frame, anchor_index);
    n_retire = anchor_index + 1;
  }

  GST_DEBUG ("retiring %d", n_retire);
  gst_ivtc_retire_fields (ivtc, n_retire);

  gst_video_frame_unmap (&dest_frame);

  GST_BUFFER_PTS (outbuf) = ivtc->current_ts;
  GST_BUFFER_DTS (outbuf) = ivtc->current_ts;
  /* FIXME this is not how to produce durations */
  GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale (GST_SECOND,
      ivtc->src_video_info.fps_d, ivtc->src_video_info.fps_n);
  GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED |
      GST_VIDEO_BUFFER_FLAG_TFF | GST_VIDEO_BUFFER_FLAG_RFF |
      GST_VIDEO_BUFFER_FLAG_ONEFIELD);
  ivtc->current_ts += GST_BUFFER_DURATION (outbuf);

}

static int
get_comb_score (GstVideoFrame * top, GstVideoFrame * bottom)
{
  int j;
  int thisline[MAX_WIDTH];
  int score = 0;
  int height;
  int width;
  int k;

  height = GST_VIDEO_FRAME_COMP_HEIGHT (top, 0);
  width = GST_VIDEO_FRAME_COMP_WIDTH (top, 0);

  memset (thisline, 0, sizeof (thisline));

  k = 0;
  /* remove a few lines from top and bottom, as they sometimes contain
   * artifacts */
  for (j = 2; j < height - 2; j++) {
    guint8 *src1 = GET_LINE_IL (top, bottom, 0, j - 1);
    guint8 *src2 = GET_LINE_IL (top, bottom, 0, j);
    guint8 *src3 = GET_LINE_IL (top, bottom, 0, j + 1);
    int i;

    for (i = 0; i < width; i++) {
      if (src2[i] < MIN (src1[i], src3[i]) - 5 ||
          src2[i] > MAX (src1[i], src3[i]) + 5) {
        if (i > 0) {
          thisline[i] += thisline[i - 1];
        }
        thisline[i]++;
        if (thisline[i] > 1000)
          thisline[i] = 1000;
      } else {
        thisline[i] = 0;
      }
      if (thisline[i] > 100) {
        score++;
      }
    }
  }

  GST_DEBUG ("score %d", score);

  return score;
}



static gboolean
plugin_init (GstPlugin * plugin)
{
  gst_element_register (plugin, "ivtc", GST_RANK_NONE, GST_TYPE_IVTC);
  gst_element_register (plugin, "combdetect", GST_RANK_NONE,
      GST_TYPE_COMB_DETECT);

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    ivtc,
    "Inverse Telecine",
    plugin_init, VERSION, "LGPL", PACKAGE_NAME, GST_PACKAGE_ORIGIN)
