From cf6cde0d6dcfedd112375a1f10d2fda65f458764 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <slomo@circular-chaos.org>
Date: Sat, 2 Aug 2008 18:30:56 +0000
Subject: gst/deinterlace2/tvtime/vfir.c: Implement the VFIR deinterlacing
 method as simple method.

Original commit message from CVS:
* gst/deinterlace2/tvtime/vfir.c: (deinterlace_line_c),
(deinterlace_line_mmx), (gst_deinterlace_method_vfir_class_init):
Implement the VFIR deinterlacing method as simple method.
---
 ChangeLog                      |   6 +++
 gst/deinterlace2/tvtime/vfir.c | 115 ++++++++++++-----------------------------
 2 files changed, 40 insertions(+), 81 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 23b8a7a1..56764059 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-08-02  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
+
+	* gst/deinterlace2/tvtime/vfir.c: (deinterlace_line_c),
+	(deinterlace_line_mmx), (gst_deinterlace_method_vfir_class_init):
+	Implement the VFIR deinterlacing method as simple method.
+
 2008-08-02  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
 
 	* gst/deinterlace2/gstdeinterlace2.c:
diff --git a/gst/deinterlace2/tvtime/vfir.c b/gst/deinterlace2/tvtime/vfir.c
index 85ed1555..56950459 100644
--- a/gst/deinterlace2/tvtime/vfir.c
+++ b/gst/deinterlace2/tvtime/vfir.c
@@ -47,15 +47,9 @@
 
 GType gst_deinterlace_method_vfir_get_type (void);
 
-typedef GstDeinterlaceMethod GstDeinterlaceMethodVFIR;
+typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodVFIR;
 
-typedef struct
-{
-  GstDeinterlaceMethodClass parent_class;
-  void (*scanline) (uint8_t * dst, uint8_t * lum_m4,
-      uint8_t * lum_m3, uint8_t * lum_m2,
-      uint8_t * lum_m1, uint8_t * lum, int size);
-} GstDeinterlaceMethodVFIRClass;
+typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodVFIRClass;
 
 /*
  * The MPEG2 spec uses a slightly harsher filter, they specify
@@ -68,11 +62,16 @@ typedef struct
   * C implementation.
   */
 static inline void
-deinterlace_line_c (uint8_t * dst, uint8_t * lum_m4,
-    uint8_t * lum_m3, uint8_t * lum_m2,
-    uint8_t * lum_m1, uint8_t * lum, int size)
+deinterlace_line_c (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
+    guint8 * dst, GstDeinterlaceScanlineData * scanlines, gint width)
 {
-  int sum;
+  gint sum;
+  guint8 *lum_m4 = scanlines->tt1;
+  guint8 *lum_m3 = scanlines->t0;
+  guint8 *lum_m2 = scanlines->m1;
+  guint8 *lum_m1 = scanlines->b0;
+  guint8 *lum = scanlines->bb1;
+  gint size = width * 2;
 
   for (; size >= 0; size--) {
     sum = -lum_m4[0];
@@ -93,11 +92,15 @@ deinterlace_line_c (uint8_t * dst, uint8_t * lum_m4,
 #ifdef BUILD_X86_ASM
 #include "mmx.h"
 static void
-deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4,
-    uint8_t * lum_m3, uint8_t * lum_m2,
-    uint8_t * lum_m1, uint8_t * lum, int size)
+deinterlace_line_mmx (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
+    guint8 * dst, GstDeinterlaceScanlineData * scanlines, gint width)
 {
   mmx_t rounder;
+  guint8 *lum_m4 = scanlines->tt1;
+  guint8 *lum_m3 = scanlines->t0;
+  guint8 *lum_m2 = scanlines->m1;
+  guint8 *lum_m1 = scanlines->b0;
+  guint8 *lum = scanlines->bb1;
 
   rounder.uw[0] = 4;
   rounder.uw[1] = 4;
@@ -106,7 +109,7 @@ deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4,
   pxor_r2r (mm7, mm7);
   movq_m2r (rounder, mm6);
 
-  for (; size > 3; size -= 4) {
+  for (; width > 1; width -= 2) {
     movd_m2r (*lum_m4, mm0);
     movd_m2r (*lum_m3, mm1);
     movd_m2r (*lum_m2, mm2);
@@ -137,94 +140,44 @@ deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4,
   emms ();
 
   /* Handle odd widths */
-  if (size > 0)
-    deinterlace_line_c (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size);
-}
-#endif
-
-static void
-deinterlace_frame_vfir (GstDeinterlaceMethod * d_method,
-    GstDeinterlace2 * object)
-{
-  GstDeinterlaceMethodVFIRClass *klass =
-      GST_DEINTERLACE_METHOD_VFIR_GET_CLASS (d_method);
-  gint line = 0;
-  uint8_t *cur_field, *last_field;
-  uint8_t *t0, *b0, *tt1, *m1, *bb1, *out_data;
-
-  cur_field =
-      GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
-  last_field =
-      GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
-
-  out_data = GST_BUFFER_DATA (object->out_buf);
-
-  if (object->field_history[object->history_count - 2].flags ==
-      PICTURE_INTERLACED_BOTTOM) {
-    memcpy (out_data, cur_field, object->line_length);
-    out_data += object->output_stride;
-  }
-
-  memcpy (out_data, cur_field, object->line_length);
-  out_data += object->output_stride;
-  line++;
-
-  for (; line < object->field_height; line++) {
-    t0 = cur_field;
-    b0 = cur_field + object->field_stride;
-
-    tt1 = last_field;
-    m1 = last_field + object->field_stride;
-    bb1 = last_field + (object->field_stride * 2);
-
-    /* set valid data for corner cases */
-    if (line == 1) {
-      tt1 = bb1;
-    } else if (line == object->field_height - 1) {
-      bb1 = tt1;
-    }
-
-    klass->scanline (out_data, tt1, t0, m1, b0, bb1, object->line_length);
-    out_data += object->output_stride;
-    cur_field += object->field_stride;
-    last_field += object->field_stride;
-
-    memcpy (out_data, cur_field, object->line_length);
-    out_data += object->output_stride;
-  }
-
-  if (object->field_history[object->history_count - 2].flags ==
-      PICTURE_INTERLACED_TOP) {
-    /* double the last scanline of the top field */
-    memcpy (out_data, cur_field, object->line_length);
+  if (width > 0) {
+    scanlines->tt1 = lum_m4;
+    scanlines->t0 = lum_m3;
+    scanlines->m1 = lum_m2;
+    scanlines->b0 = lum_m1;
+    scanlines->bb1 = lum;
+
+    deinterlace_line_c (self, parent, dst, scanlines, width);
   }
 }
+#endif
 
 G_DEFINE_TYPE (GstDeinterlaceMethodVFIR, gst_deinterlace_method_vfir,
-    GST_TYPE_DEINTERLACE_METHOD);
+    GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
 
 static void
 gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
 {
   GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
+  GstDeinterlaceSimpleMethodClass *dism_class =
+      (GstDeinterlaceSimpleMethodClass *) klass;
 #ifdef BUILD_X86_ASM
   guint cpu_flags = oil_cpu_get_flags ();
 #endif
 
   dim_class->fields_required = 2;
-  dim_class->deinterlace_frame = deinterlace_frame_vfir;
   dim_class->name = "Blur Vertical";
   dim_class->nick = "vfir";
   dim_class->latency = 0;
 
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMX) {
-    klass->scanline = deinterlace_line_mmx;
+    dism_class->interpolate_scanline = deinterlace_line_mmx;
   } else {
-    klass->scanline = deinterlace_line_c;
+    dism_class->interpolate_scanline = deinterlace_line_c;
   }
 #else
-  klass->scanline = deinterlace_line_c;
+  dism_class->interpolate_scanline = deinterlace_line_c;
 #endif
 }
 
-- 
cgit v1.2.1