deinterlace: Refactor deinterlacing as preparation for supporting more color formats
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 21 Apr 2010 15:00:05 +0000 (17:00 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 29 Apr 2010 17:28:23 +0000 (19:28 +0200)
15 files changed:
gst/deinterlace/Makefile.am
gst/deinterlace/gstdeinterlace.c
gst/deinterlace/gstdeinterlace.h
gst/deinterlace/tvtime/greedy.c
gst/deinterlace/tvtime/greedyh.asm
gst/deinterlace/tvtime/greedyh.c
gst/deinterlace/tvtime/linear.c
gst/deinterlace/tvtime/linearblend.c
gst/deinterlace/tvtime/scalerbob.c
gst/deinterlace/tvtime/tomsmocomp.c
gst/deinterlace/tvtime/tomsmocomp/TomsMoCompAll.inc
gst/deinterlace/tvtime/vfir.c
gst/deinterlace/tvtime/weave.c
gst/deinterlace/tvtime/weavebff.c
gst/deinterlace/tvtime/weavetff.c

index c5a7ef043dd0a3be9e716df6169ce5fcbefa4c55..b5a1bca3760fd1d54edc7c12ba35ddd0298b5916 100644 (file)
@@ -2,10 +2,10 @@ plugin_LTLIBRARIES = libgstdeinterlace.la
 
 libgstdeinterlace_la_SOURCES = \
        gstdeinterlace.c \
+       tvtime/tomsmocomp.c \
        tvtime/greedy.c \
        tvtime/greedyh.c \
        tvtime/vfir.c \
-       tvtime/tomsmocomp.c \
        tvtime/weavetff.c \
        tvtime/weavebff.c \
        tvtime/weave.c \
index 0f7af634b6989d8e46338f4977f01b6c53a86728..b3ace11ec16909cd7059596b71ce3a03601eb0b6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * GStreamer
  * Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
- * Copyright (C) 2008-2009 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008-2010 Sebastian Dröge <slomo@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
@@ -70,25 +70,104 @@ enum
 
 G_DEFINE_TYPE (GstDeinterlaceMethod, gst_deinterlace_method, GST_TYPE_OBJECT);
 
-static void
-gst_deinterlace_method_class_init (GstDeinterlaceMethodClass * klass)
+static gboolean
+gst_deinterlace_method_supported (GType type, GstVideoFormat format, gint width,
+    gint height)
 {
+  GstDeinterlaceMethodClass *klass =
+      GST_DEINTERLACE_METHOD_CLASS (g_type_class_ref (type));
+  gboolean ret;
+
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    ret = TRUE;
+  else
+    ret = klass->supported (klass, format, width, height);
+  g_type_class_unref (klass);
+
+  return ret;
+}
 
+static gboolean
+gst_deinterlace_method_supported_impl (GstDeinterlaceMethodClass * klass,
+    GstVideoFormat format, gint width, gint height)
+{
+  switch (format) {
+    case GST_VIDEO_FORMAT_YUY2:
+      return (klass->deinterlace_frame_yuy2 != NULL);
+    case GST_VIDEO_FORMAT_YVYU:
+      return (klass->deinterlace_frame_yvyu != NULL);
+    default:
+      return FALSE;
+  }
 }
 
 static void
-gst_deinterlace_method_init (GstDeinterlaceMethod * self)
+gst_deinterlace_method_setup (GstDeinterlaceMethod * self,
+    GstVideoFormat format, gint width, gint height)
 {
+  GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
 
+  klass->setup (self, format, width, height);
 }
 
 static void
-gst_deinterlace_method_deinterlace_frame (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, GstBuffer * outbuf)
+gst_deinterlace_method_setup_impl (GstDeinterlaceMethod * self,
+    GstVideoFormat format, gint width, gint height)
 {
+  gint i;
   GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
 
-  klass->deinterlace_frame (self, parent, outbuf);
+  self->format = format;
+  self->frame_width = width;
+  self->frame_height = height;
+
+  self->deinterlace_frame = NULL;
+
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return;
+
+  for (i = 0; i < 4; i++) {
+    self->width[i] = gst_video_format_get_component_width (format, i, width);
+    self->height[i] = gst_video_format_get_component_height (format, i, height);
+    self->offset[i] =
+        gst_video_format_get_component_offset (format, i, width, height);
+    self->row_stride[i] = gst_video_format_get_row_stride (format, i, width);
+    self->pixel_stride[i] = gst_video_format_get_pixel_stride (format, i);
+  }
+
+  switch (format) {
+    case GST_VIDEO_FORMAT_YUY2:
+      self->deinterlace_frame = klass->deinterlace_frame_yuy2;
+      break;
+    case GST_VIDEO_FORMAT_YVYU:
+      self->deinterlace_frame = klass->deinterlace_frame_yvyu;
+      break;
+    default:
+      self->deinterlace_frame = NULL;
+      break;
+  }
+}
+
+static void
+gst_deinterlace_method_class_init (GstDeinterlaceMethodClass * klass)
+{
+  klass->setup = gst_deinterlace_method_setup_impl;
+  klass->supported = gst_deinterlace_method_supported_impl;
+}
+
+static void
+gst_deinterlace_method_init (GstDeinterlaceMethod * self)
+{
+  self->format = GST_VIDEO_FORMAT_UNKNOWN;
+}
+
+static void
+gst_deinterlace_method_deinterlace_frame (GstDeinterlaceMethod * self,
+    const GstDeinterlaceField * history, guint history_count,
+    GstBuffer * outbuf)
+{
+  g_assert (self->deinterlace_frame != NULL);
+  self->deinterlace_frame (self, history, history_count, outbuf);
 }
 
 static gint
@@ -107,144 +186,215 @@ gst_deinterlace_method_get_latency (GstDeinterlaceMethod * self)
   return klass->latency;
 }
 
-
 G_DEFINE_TYPE (GstDeinterlaceSimpleMethod, gst_deinterlace_simple_method,
     GST_TYPE_DEINTERLACE_METHOD);
 
+static gboolean
+gst_deinterlace_simple_method_supported (GstDeinterlaceMethodClass * mklass,
+    GstVideoFormat format, gint width, gint height)
+{
+  GstDeinterlaceSimpleMethodClass *klass =
+      GST_DEINTERLACE_SIMPLE_METHOD_CLASS (mklass);
+
+  if (!GST_DEINTERLACE_METHOD_CLASS
+      (gst_deinterlace_simple_method_parent_class)->supported (mklass, format,
+          width, height))
+    return FALSE;
+
+  switch (format) {
+    case GST_VIDEO_FORMAT_YUY2:
+      return (klass->interpolate_scanline_yuy2 != NULL
+          && klass->copy_scanline_yuy2 != NULL);
+    case GST_VIDEO_FORMAT_YVYU:
+      return (klass->interpolate_scanline_yvyu != NULL
+          && klass->copy_scanline_yvyu != NULL);
+    default:
+      return FALSE;
+  }
+}
+
 static void
-gst_deinterlace_simple_method_interpolate_scanline (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+    gst_deinterlace_simple_method_interpolate_scanline_packed
+    (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
 {
-  oil_memcpy (out, scanlines->m1, parent->row_stride);
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[0]);
 }
 
 static void
-gst_deinterlace_simple_method_copy_scanline (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+gst_deinterlace_simple_method_copy_scanline_packed (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
 {
-  oil_memcpy (out, scanlines->m0, parent->row_stride);
+  oil_memcpy (out, scanlines->m0, self->parent.row_stride[0]);
 }
 
 static void
-gst_deinterlace_simple_method_deinterlace_frame (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, GstBuffer * outbuf)
+gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod *
+    method, const GstDeinterlaceField * history, guint history_count,
+    GstBuffer * outbuf)
 {
-  GstDeinterlaceSimpleMethodClass *dsm_class =
-      GST_DEINTERLACE_SIMPLE_METHOD_GET_CLASS (self);
+  GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
   GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
   GstDeinterlaceScanlineData scanlines;
   guint8 *out = GST_BUFFER_DATA (outbuf);
   guint8 *field0 = NULL, *field1 = NULL, *field2 = NULL, *field3 = NULL;
-  gint cur_field_idx = parent->history_count - dm_class->fields_required;
-  guint cur_field_flags = parent->field_history[cur_field_idx].flags;
+  gint cur_field_idx = history_count - dm_class->fields_required;
+  guint cur_field_flags = history[cur_field_idx].flags;
   gint line;
+  gint field_height = self->parent.frame_height / 2;
+  gint row_stride = self->parent.row_stride[0];
+  gint field_stride = self->parent.row_stride[0] * 2;
+
+  g_assert (self->interpolate_scanline_packed != NULL);
+  g_assert (self->copy_scanline_packed != NULL);
 
-  field0 = GST_BUFFER_DATA (parent->field_history[cur_field_idx].buf);
+  field0 = GST_BUFFER_DATA (history[cur_field_idx].buf);
+  if (history[cur_field_idx].flags & PICTURE_INTERLACED_BOTTOM)
+    field0 += row_stride;
 
   g_return_if_fail (dm_class->fields_required <= 4);
 
-  if (dm_class->fields_required >= 2)
-    field1 = GST_BUFFER_DATA (parent->field_history[cur_field_idx + 1].buf);
-  if (dm_class->fields_required >= 3)
-    field2 = GST_BUFFER_DATA (parent->field_history[cur_field_idx + 2].buf);
-  if (dm_class->fields_required >= 4)
-    field3 = GST_BUFFER_DATA (parent->field_history[cur_field_idx + 3].buf);
+  if (dm_class->fields_required >= 2) {
+    field1 = GST_BUFFER_DATA (history[cur_field_idx + 1].buf);
+    if (history[cur_field_idx + 1].flags & PICTURE_INTERLACED_BOTTOM)
+      field1 += row_stride;
+  }
+
+  if (dm_class->fields_required >= 3) {
+    field2 = GST_BUFFER_DATA (history[cur_field_idx + 2].buf);
+    if (history[cur_field_idx + 2].flags & PICTURE_INTERLACED_BOTTOM)
+      field2 += row_stride;
+  }
+
+  if (dm_class->fields_required >= 4) {
+    field3 = GST_BUFFER_DATA (history[cur_field_idx + 3].buf);
+    if (history[cur_field_idx + 3].flags & PICTURE_INTERLACED_BOTTOM)
+      field3 += row_stride;
+  }
 
 
   if (cur_field_flags == PICTURE_INTERLACED_BOTTOM) {
     /* double the first scanline of the bottom field */
-    oil_memcpy (out, field0, parent->row_stride);
-    out += parent->row_stride;
+    oil_memcpy (out, field0, row_stride);
+    out += row_stride;
   }
 
-  oil_memcpy (out, field0, parent->row_stride);
-  out += parent->row_stride;
+  oil_memcpy (out, field0, row_stride);
+  out += row_stride;
 
-  for (line = 2; line <= parent->field_height; line++) {
+  for (line = 2; line <= field_height; line++) {
 
     memset (&scanlines, 0, sizeof (scanlines));
     scanlines.bottom_field = (cur_field_flags == PICTURE_INTERLACED_BOTTOM);
 
     /* interp. scanline */
     scanlines.t0 = field0;
-    scanlines.b0 = field0 + parent->field_stride;
+    scanlines.b0 = field0 + field_stride;
 
     if (field1 != NULL) {
       scanlines.tt1 = field1;
-      scanlines.m1 = field1 + parent->field_stride;
-      scanlines.bb1 = field1 + parent->field_stride * 2;
-      field1 += parent->field_stride;
+      scanlines.m1 = field1 + field_stride;
+      scanlines.bb1 = field1 + field_stride * 2;
+      field1 += field_stride;
     }
 
     if (field2 != NULL) {
       scanlines.t2 = field2;
-      scanlines.b2 = field2 + parent->field_stride;
+      scanlines.b2 = field2 + field_stride;
     }
 
     if (field3 != NULL) {
       scanlines.tt3 = field3;
-      scanlines.m3 = field3 + parent->field_stride;
-      scanlines.bb3 = field3 + parent->field_stride * 2;
-      field3 += parent->field_stride;
+      scanlines.m3 = field3 + field_stride;
+      scanlines.bb3 = field3 + field_stride * 2;
+      field3 += field_stride;
     }
 
     /* set valid data for corner cases */
     if (line == 2) {
       scanlines.tt1 = scanlines.bb1;
       scanlines.tt3 = scanlines.bb3;
-    } else if (line == parent->field_height) {
+    } else if (line == field_height) {
       scanlines.bb1 = scanlines.tt1;
       scanlines.bb3 = scanlines.tt3;
     }
 
-    dsm_class->interpolate_scanline (self, parent, out, &scanlines,
-        parent->frame_width);
-    out += parent->row_stride;
+    self->interpolate_scanline_packed (self, out, &scanlines);
+    out += row_stride;
 
     memset (&scanlines, 0, sizeof (scanlines));
     scanlines.bottom_field = (cur_field_flags == PICTURE_INTERLACED_BOTTOM);
 
     /* copy a scanline */
     scanlines.tt0 = field0;
-    scanlines.m0 = field0 + parent->field_stride;
-    scanlines.bb0 = field0 + parent->field_stride * 2;
-    field0 += parent->field_stride;
+    scanlines.m0 = field0 + field_stride;
+    scanlines.bb0 = field0 + field_stride * 2;
+    field0 += field_stride;
 
     if (field1 != NULL) {
       scanlines.t1 = field1;
-      scanlines.b1 = field1 + parent->field_stride;
+      scanlines.b1 = field1 + field_stride;
     }
 
     if (field2 != NULL) {
       scanlines.tt2 = field2;
-      scanlines.m2 = field2 + parent->field_stride;
-      scanlines.bb2 = field2 + parent->field_stride * 2;
-      field2 += parent->field_stride;
+      scanlines.m2 = field2 + field_stride;
+      scanlines.bb2 = field2 + field_stride * 2;
+      field2 += field_stride;
     }
 
     if (field3 != NULL) {
       scanlines.t3 = field3;
-      scanlines.b3 = field3 + parent->field_stride;
+      scanlines.b3 = field3 + field_stride;
     }
 
     /* set valid data for corner cases */
-    if (line == parent->field_height) {
+    if (line == field_height) {
       scanlines.bb0 = scanlines.tt0;
       scanlines.b1 = scanlines.t1;
       scanlines.bb2 = scanlines.tt2;
       scanlines.b3 = scanlines.t3;
     }
 
-    dsm_class->copy_scanline (self, parent, out, &scanlines,
-        parent->frame_width);
-    out += parent->row_stride;
+    self->copy_scanline_packed (self, out, &scanlines);
+    out += row_stride;
   }
 
   if (cur_field_flags == PICTURE_INTERLACED_TOP) {
     /* double the last scanline of the top field */
-    oil_memcpy (out, field0, parent->row_stride);
+    oil_memcpy (out, field0, row_stride);
+  }
+}
+
+static void
+gst_deinterlace_simple_method_setup (GstDeinterlaceMethod * method,
+    GstVideoFormat format, gint width, gint height)
+{
+  GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
+  GstDeinterlaceSimpleMethodClass *klass =
+      GST_DEINTERLACE_SIMPLE_METHOD_GET_CLASS (self);
+
+  GST_DEINTERLACE_METHOD_CLASS
+      (gst_deinterlace_simple_method_parent_class)->setup (method, format,
+      width, height);
+
+  self->interpolate_scanline_packed = NULL;
+  self->copy_scanline_packed = NULL;
+
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return;
+
+  switch (format) {
+    case GST_VIDEO_FORMAT_YUY2:
+      self->interpolate_scanline_packed = klass->interpolate_scanline_yuy2;
+      self->copy_scanline_packed = klass->copy_scanline_yuy2;
+      break;
+    case GST_VIDEO_FORMAT_YVYU:
+      self->interpolate_scanline_packed = klass->interpolate_scanline_yvyu;
+      self->copy_scanline_packed = klass->copy_scanline_yvyu;
+      break;
+    default:
+      break;
   }
 }
 
@@ -254,12 +404,22 @@ gst_deinterlace_simple_method_class_init (GstDeinterlaceSimpleMethodClass *
 {
   GstDeinterlaceMethodClass *dm_class = (GstDeinterlaceMethodClass *) klass;
 
-  dm_class->deinterlace_frame = gst_deinterlace_simple_method_deinterlace_frame;
+  dm_class->deinterlace_frame_yuy2 =
+      gst_deinterlace_simple_method_deinterlace_frame_packed;
+  dm_class->deinterlace_frame_yvyu =
+      gst_deinterlace_simple_method_deinterlace_frame_packed;
   dm_class->fields_required = 2;
-
-  klass->interpolate_scanline =
-      gst_deinterlace_simple_method_interpolate_scanline;
-  klass->copy_scanline = gst_deinterlace_simple_method_copy_scanline;
+  dm_class->setup = gst_deinterlace_simple_method_setup;
+  dm_class->supported = gst_deinterlace_simple_method_supported;
+
+  klass->interpolate_scanline_yuy2 =
+      gst_deinterlace_simple_method_interpolate_scanline_packed;
+  klass->copy_scanline_yuy2 =
+      gst_deinterlace_simple_method_copy_scanline_packed;
+  klass->interpolate_scanline_yvyu =
+      gst_deinterlace_simple_method_interpolate_scanline_packed;
+  klass->copy_scanline_yvyu =
+      gst_deinterlace_simple_method_copy_scanline_packed;
 }
 
 static void
@@ -417,59 +577,81 @@ _do_init (GType object_type)
 GST_BOILERPLATE_FULL (GstDeinterlace, gst_deinterlace, GstElement,
     GST_TYPE_ELEMENT, _do_init);
 
+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;
+
   GST_DEBUG_OBJECT (self, "Setting new method %d", method);
 
   if (self->method) {
+    if (self->method_id == method &&
+        gst_deinterlace_method_supported (G_TYPE_FROM_INSTANCE (self->method),
+            self->format, self->width, self->height)) {
+      GST_DEBUG_OBJECT (self, "Reusing current method");
+      return;
+    }
+
     gst_child_proxy_child_removed (GST_OBJECT (self),
         GST_OBJECT (self->method));
     gst_object_unparent (GST_OBJECT (self->method));
     self->method = NULL;
   }
 
-  switch (method) {
-    case GST_DEINTERLACE_TOMSMOCOMP:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_TOMSMOCOMP, NULL);
-      break;
-    case GST_DEINTERLACE_GREEDY_H:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_GREEDY_H, NULL);
-      break;
-    case GST_DEINTERLACE_GREEDY_L:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_GREEDY_L, NULL);
-      break;
-    case GST_DEINTERLACE_VFIR:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_VFIR, NULL);
-      break;
-    case GST_DEINTERLACE_LINEAR:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_LINEAR, NULL);
-      break;
-    case GST_DEINTERLACE_LINEAR_BLEND:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_LINEAR_BLEND, NULL);
-      break;
-    case GST_DEINTERLACE_SCALER_BOB:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_SCALER_BOB, NULL);
-      break;
-    case GST_DEINTERLACE_WEAVE:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_WEAVE, NULL);
-      break;
-    case GST_DEINTERLACE_WEAVE_TFF:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_WEAVE_TFF, NULL);
-      break;
-    case GST_DEINTERLACE_WEAVE_BFF:
-      self->method = g_object_new (GST_TYPE_DEINTERLACE_WEAVE_BFF, NULL);
-      break;
-    default:
-      GST_WARNING_OBJECT (self, "Invalid Deinterlacer Method");
-      return;
+  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, self->format,
+          self->width, self->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, self->format, self->width,
+              self->height)) {
+        GST_DEBUG_OBJECT (self, "Using method %d", i);
+        method_type = tmp;
+        break;
+      }
+    }
+    /* If we get here we must have invalid caps! */
+    g_assert (method_type != G_TYPE_INVALID);
   }
 
+  self->method = g_object_new (method_type, NULL);
   self->method_id = method;
 
   gst_object_set_name (GST_OBJECT (self->method), "method");
   gst_object_set_parent (GST_OBJECT (self->method), GST_OBJECT (self));
   gst_child_proxy_child_added (GST_OBJECT (self), GST_OBJECT (self->method));
+
+  if (self->method)
+    gst_deinterlace_method_setup (self->method, self->format, self->width,
+        self->height);
 }
 
 static gboolean
@@ -757,7 +939,7 @@ gst_deinterlace_reset_history (GstDeinterlace * self)
     }
   }
   memset (self->field_history, 0,
-      GST_DEINTERLACE_MAX_FIELD_HISTORY * sizeof (GstPicture));
+      GST_DEINTERLACE_MAX_FIELD_HISTORY * sizeof (GstDeinterlaceField));
   self->history_count = 0;
 
   if (self->last_buffer)
@@ -770,13 +952,11 @@ gst_deinterlace_reset (GstDeinterlace * self)
 {
   GST_DEBUG_OBJECT (self, "Resetting internal state");
 
-  self->row_stride = 0;
-  self->frame_width = 0;
-  self->frame_height = 0;
-  self->frame_rate_n = 0;
-  self->frame_rate_d = 0;
-  self->field_height = 0;
-  self->field_stride = 0;
+  self->format = GST_VIDEO_FORMAT_UNKNOWN;
+  self->width = 0;
+  self->height = 0;
+  self->frame_size = 0;
+  self->fps_n = self->fps_d = 0;
 
   gst_segment_init (&self->segment, GST_FORMAT_TIME);
 
@@ -948,13 +1128,11 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer)
     GST_DEBUG_OBJECT (self, "Top field first");
     field1 = gst_buffer_ref (buffer);
     field1_flags = PICTURE_INTERLACED_TOP;
-    field2 = gst_buffer_create_sub (buffer, self->row_stride,
-        GST_BUFFER_SIZE (buffer) - self->row_stride);
+    field2 = gst_buffer_ref (buffer);
     field2_flags = PICTURE_INTERLACED_BOTTOM;
   } else {
     GST_DEBUG_OBJECT (self, "Bottom field first");
-    field1 = gst_buffer_create_sub (buffer, self->row_stride,
-        GST_BUFFER_SIZE (buffer) - self->row_stride);
+    field1 = gst_buffer_ref (buffer);
     field1_flags = PICTURE_INTERLACED_BOTTOM;
     field2 = gst_buffer_ref (buffer);
     field2_flags = PICTURE_INTERLACED_TOP;
@@ -1172,7 +1350,8 @@ gst_deinterlace_chain (GstPad * pad, GstBuffer * buf)
         ret = GST_FLOW_OK;
       } else {
         /* do magic calculus */
-        gst_deinterlace_method_deinterlace_frame (self->method, self, outbuf);
+        gst_deinterlace_method_deinterlace_frame (self->method,
+            self->field_history, self->history_count, outbuf);
 
         gst_buffer_unref (gst_deinterlace_pop_history (self));
 
@@ -1249,7 +1428,8 @@ gst_deinterlace_chain (GstPad * pad, GstBuffer * buf)
         ret = GST_FLOW_OK;
       } else {
         /* do magic calculus */
-        gst_deinterlace_method_deinterlace_frame (self->method, self, outbuf);
+        gst_deinterlace_method_deinterlace_frame (self->method,
+            self->field_history, self->history_count, outbuf);
 
         gst_buffer_unref (gst_deinterlace_pop_history (self));
 
@@ -1476,33 +1656,23 @@ gst_deinterlace_setcaps (GstPad * pad, GstCaps * caps)
   gboolean res = TRUE;
   GstDeinterlace *self = GST_DEINTERLACE (gst_pad_get_parent (pad));
   GstPad *otherpad;
-  GstStructure *structure;
-  GstVideoFormat fmt;
-  guint32 fourcc;
   GstCaps *othercaps;
 
   otherpad = (pad == self->srcpad) ? self->sinkpad : self->srcpad;
 
-  structure = gst_caps_get_structure (caps, 0);
-
-  res = gst_structure_get_int (structure, "width", &self->frame_width);
-  res &= gst_structure_get_int (structure, "height", &self->frame_height);
-  res &=
-      gst_structure_get_fraction (structure, "framerate", &self->frame_rate_n,
-      &self->frame_rate_d);
-  res &= gst_structure_get_fourcc (structure, "format", &fourcc);
-  if (pad == self->sinkpad) {
+  res =
+      gst_video_format_parse_caps (caps, &self->format, &self->width,
+      &self->height);
+  res &= gst_video_parse_caps_framerate (caps, &self->fps_n, &self->fps_d);
+  if (pad == self->sinkpad)
     res &= gst_video_format_parse_caps_interlaced (caps, &self->interlaced);
-  } else {
-    res &= gst_video_format_parse_caps_interlaced (caps, &self->src_interlaced);
-  }
   if (!res)
     goto invalid_caps;
 
   if ((self->interlaced || self->mode == GST_DEINTERLACE_MODE_INTERLACED) &&
       self->fields == GST_DEINTERLACE_ALL
       && self->mode != GST_DEINTERLACE_MODE_DISABLED) {
-    gint fps_n = self->frame_rate_n, fps_d = self->frame_rate_d;
+    gint fps_n = self->fps_n, fps_d = self->fps_d;
 
     if (!gst_fraction_double (&fps_n, &fps_d, otherpad != self->srcpad))
       goto invalid_caps;
@@ -1516,39 +1686,22 @@ gst_deinterlace_setcaps (GstPad * pad, GstCaps * caps)
   }
 
   if (otherpad == self->srcpad && self->mode != GST_DEINTERLACE_MODE_DISABLED) {
-    GstStructure *s;
-
     othercaps = gst_caps_make_writable (othercaps);
-    s = gst_caps_get_structure (othercaps, 0);
-    gst_structure_remove_field (s, "interlaced");
+    gst_caps_set_simple (othercaps, "interlaced", G_TYPE_BOOLEAN, FALSE, NULL);
   }
 
   if (!gst_pad_set_caps (otherpad, othercaps))
     goto caps_not_accepted;
 
-  self->field_height = self->frame_height / 2;
-
-  fmt = gst_video_format_from_fourcc (fourcc);
-
-  /* TODO: only true if fields are subbuffers of interlaced frames,
-     change when the buffer-fields concept has landed */
-  self->field_stride =
-      gst_video_format_get_row_stride (fmt, 0, self->frame_width) * 2;
-
-  /* in bytes */
-  self->row_stride =
-      gst_video_format_get_row_stride (fmt, 0, self->frame_width);
   self->frame_size =
-      gst_video_format_get_size (fmt, self->frame_width, self->frame_height);
+      gst_video_format_get_size (self->format, self->width, self->height);
 
   if (self->fields == GST_DEINTERLACE_ALL && otherpad == self->srcpad)
     self->field_duration =
-        gst_util_uint64_scale (GST_SECOND, self->frame_rate_d,
-        self->frame_rate_n);
+        gst_util_uint64_scale (GST_SECOND, self->fps_d, self->fps_n);
   else
     self->field_duration =
-        gst_util_uint64_scale (GST_SECOND, self->frame_rate_d,
-        2 * self->frame_rate_n);
+        gst_util_uint64_scale (GST_SECOND, self->fps_d, 2 * self->fps_n);
 
   if (pad == self->sinkpad) {
     gst_caps_replace (&self->sink_caps, caps);
@@ -1558,6 +1711,10 @@ gst_deinterlace_setcaps (GstPad * pad, GstCaps * caps)
     gst_caps_replace (&self->sink_caps, othercaps);
   }
 
+  gst_deinterlace_set_method (self, self->method_id);
+  gst_deinterlace_method_setup (self->method, self->format, self->width,
+      self->height);
+
   GST_DEBUG_OBJECT (pad, "Set caps: %" GST_PTR_FORMAT, caps);
   GST_DEBUG_OBJECT (pad, "Other caps: %" GST_PTR_FORMAT, othercaps);
 
index d77128f4fbd259968b0db64fae5a7a234147243c..7e9602fad7e99e647b1c6198d231d621301aa884 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * GStreamer
  * Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
- * Copyright (C) 2008-2009 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008-2010 Sebastian Dröge <slomo@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
@@ -24,6 +24,7 @@
 
 #include <gst/gst.h>
 #include <gst/video/video.h>
+
 #include <liboil/liboil.h>
 #include <liboil/liboilcpu.h>
 #include <liboil/liboilfunction.h>
@@ -61,12 +62,39 @@ typedef struct _GstDeinterlaceClass GstDeinterlaceClass;
 typedef struct _GstDeinterlaceMethod GstDeinterlaceMethod;
 typedef struct _GstDeinterlaceMethodClass GstDeinterlaceMethodClass;
 
+
+#define PICTURE_PROGRESSIVE 0
+#define PICTURE_INTERLACED_BOTTOM 1
+#define PICTURE_INTERLACED_TOP 2
+#define PICTURE_INTERLACED_MASK (PICTURE_INTERLACED_BOTTOM | PICTURE_INTERLACED_TOP)
+
+typedef struct
+{
+  /* pointer to the start of data for this field */
+  GstBuffer *buf;
+  /* see PICTURE_ flags in *.c */
+  guint flags;
+} GstDeinterlaceField;
+
 /*
  * This structure defines the deinterlacer plugin.
  */
 
+
+typedef void (*GstDeinterlaceMethodDeinterlaceFunction) (GstDeinterlaceMethod *self, const GstDeinterlaceField *history, guint history_count, GstBuffer *outbuf);
+
 struct _GstDeinterlaceMethod {
   GstObject parent;
+
+  GstVideoFormat format;
+  gint frame_width, frame_height;
+  gint width[4];
+  gint height[4];
+  gint offset[4];
+  gint row_stride[4];
+  gint pixel_stride[4];
+
+  GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame;
 };
 
 struct _GstDeinterlaceMethodClass {
@@ -74,7 +102,12 @@ struct _GstDeinterlaceMethodClass {
   guint fields_required;
   guint latency;
 
-  void (*deinterlace_frame) (GstDeinterlaceMethod *self, GstDeinterlace * parent, GstBuffer *outbuf);
+  gboolean (*supported) (GstDeinterlaceMethodClass *klass, GstVideoFormat format, gint width, gint height);
+
+  void (*setup) (GstDeinterlaceMethod *self, GstVideoFormat format, gint width, gint height);
+
+  GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_yuy2;
+  GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_yvyu;
 
   const gchar *name;
   const gchar *nick;
@@ -99,10 +132,10 @@ typedef struct _GstDeinterlaceScanlineData GstDeinterlaceScanlineData;
  */
 
 struct _GstDeinterlaceScanlineData {
- guint8 *tt0, *t0, *m0, *b0, *bb0;
- guint8 *tt1, *t1, *m1, *b1, *bb1;
- guint8 *tt2, *t2, *m2, *b2, *bb2;
- guint8 *tt3, *t3, *m3, *b3, *bb3;
const guint8 *tt0, *t0, *m0, *b0, *bb0;
const guint8 *tt1, *t1, *m1, *b1, *bb1;
const guint8 *tt2, *t2, *m2, *b2, *bb2;
const guint8 *tt3, *t3, *m3, *b3, *bb3;
  gboolean bottom_field;
 };
 
@@ -130,35 +163,29 @@ struct _GstDeinterlaceScanlineData {
  * All other values are NULL.
  */
 
+typedef void (*GstDeinterlaceSimpleMethodPackedFunction) (GstDeinterlaceSimpleMethod *self, guint8 *out, const GstDeinterlaceScanlineData *scanlines);
+
 struct _GstDeinterlaceSimpleMethod {
   GstDeinterlaceMethod parent;
+
+  GstDeinterlaceSimpleMethodPackedFunction interpolate_scanline_packed;
+  GstDeinterlaceSimpleMethodPackedFunction copy_scanline_packed;
 };
 
 struct _GstDeinterlaceSimpleMethodClass {
   GstDeinterlaceMethodClass parent_class;
 
-  void (*interpolate_scanline) (GstDeinterlaceMethod *self, GstDeinterlace * parent, guint8 *out, GstDeinterlaceScanlineData *scanlines, gint width);
-  void (*copy_scanline) (GstDeinterlaceMethod *self, GstDeinterlace * parent, guint8 *out, GstDeinterlaceScanlineData *scanlines, gint width);
+  /* Packed formats */
+  GstDeinterlaceSimpleMethodPackedFunction interpolate_scanline_yuy2;
+  GstDeinterlaceSimpleMethodPackedFunction copy_scanline_yuy2;
+  GstDeinterlaceSimpleMethodPackedFunction interpolate_scanline_yvyu;
+  GstDeinterlaceSimpleMethodPackedFunction copy_scanline_yvyu;
 };
 
 GType gst_deinterlace_simple_method_get_type (void);
 
-
 #define GST_DEINTERLACE_MAX_FIELD_HISTORY 10
 
-#define PICTURE_PROGRESSIVE 0
-#define PICTURE_INTERLACED_BOTTOM 1
-#define PICTURE_INTERLACED_TOP 2
-#define PICTURE_INTERLACED_MASK (PICTURE_INTERLACED_BOTTOM | PICTURE_INTERLACED_TOP)
-
-typedef struct
-{
-  /* pointer to the start of data for this field */
-  GstBuffer *buf;
-  /* see PICTURE_ flags in *.c */
-  guint flags;
-} GstPicture;
-
 typedef enum
 {
   GST_DEINTERLACE_TOMSMOCOMP,
@@ -210,42 +237,20 @@ struct _GstDeinterlace
   GstDeinterlaceMethods method_id;
   GstDeinterlaceMethod *method;
 
-  guint frame_size;
-  gint frame_rate_n, frame_rate_d;
-  gboolean interlaced;
-  gboolean src_interlaced;
-
-  /* Number of bytes of actual data in each scanline.  May be less than
-     OverlayPitch since the overlay's scanlines might have alignment
-     requirements.  Generally equal to FrameWidth * 2.
-   */
-  guint row_stride;
-
-  /* Number of pixels in each scanline. */
-  gint frame_width;
+  GstVideoFormat format;
+  gint width, height; /* frame width & height */
+  guint frame_size; /* frame size in bytes */
+  gint fps_n, fps_d; /* frame rate */
+  gboolean interlaced; /* is input interlaced? */
 
-  /* Number of scanlines per frame. */
-  gint frame_height;
-
-  /* Number of scanlines per field.  FrameHeight / 2, mostly for
-     cleanliness so we don't have to keep dividing FrameHeight by 2.
-   */
-  gint field_height;
-
-  /* distance between lines in image
-     need not match the pixel width
-   */
-  guint field_stride;
-
-  /* Duration of one field */
-  GstClockTime field_duration;
+  GstClockTime field_duration; /* Duration of one field */
 
   /* The most recent pictures 
      PictureHistory[0] is always the most recent.
      Pointers are NULL if the picture in question isn't valid, e.g. because
      the program just started or a picture was skipped.
    */
-  GstPicture field_history[GST_DEINTERLACE_MAX_FIELD_HISTORY];
+  GstDeinterlaceField field_history[GST_DEINTERLACE_MAX_FIELD_HISTORY];
   guint history_count;
 
   /* Set to TRUE if we're in still frame mode,
@@ -278,4 +283,5 @@ struct _GstDeinterlaceClass
 GType gst_deinterlace_get_type (void);
 
 G_END_DECLS
+
 #endif /* __GST_DEINTERLACE_H__ */
index 293d82faa219176e4922c97f767202c9e3f7fe33..3e8a8210e041327a29c5c7f052101d9159c3c8bb 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 2000 Tom Barry  All rights reserved.
  * mmx.h port copyright (c) 2002 Billy Biggs <vektor@dumbterm.net>.
  *
- * Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <slomo@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
@@ -32,8 +32,6 @@
 # include "config.h"
 #endif
 
-#include "_stdint.h"
-
 #include "gstdeinterlace.h"
 #include <string.h>
 
@@ -57,8 +55,9 @@ typedef struct
 typedef struct
 {
   GstDeinterlaceMethodClass parent_class;
-  void (*scanline) (GstDeinterlaceMethodGreedyL * self, uint8_t * L2,
-      uint8_t * L1, uint8_t * L3, uint8_t * L2P, uint8_t * Dest, int size);
+  void (*scanline) (GstDeinterlaceMethodGreedyL * self, const guint8 * L2,
+      const guint8 * L1, const guint8 * L3, const guint8 * L2P, guint8 * Dest,
+      gint width);
 } GstDeinterlaceMethodGreedyLClass;
 
 // This is a simple lightweight DeInterlace method that uses little CPU time
@@ -74,11 +73,11 @@ typedef struct
 // Blended Clip but this give too good results for the CPU to ignore here.
 
 static inline void
-deinterlace_greedy_packed422_scanline_c (GstDeinterlaceMethodGreedyL * self,
-    uint8_t * m0, uint8_t * t1,
-    uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
+deinterlace_greedy_scanline_c (GstDeinterlaceMethodGreedyL * self,
+    const guint8 * m0, const guint8 * t1,
+    const guint8 * b1, const guint8 * m2, guint8 * output, gint width)
 {
-  int avg, l2_diff, lp2_diff, max, min, best;
+  gint avg, l2_diff, lp2_diff, max, min, best;
   guint max_comb = self->max_comb;
 
   // L2 == m0
@@ -124,9 +123,9 @@ deinterlace_greedy_packed422_scanline_c (GstDeinterlaceMethodGreedyL * self,
 #ifdef BUILD_X86_ASM
 #include "mmx.h"
 static void
-deinterlace_greedy_packed422_scanline_mmx (GstDeinterlaceMethodGreedyL * self,
-    uint8_t * m0, uint8_t * t1,
-    uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
+deinterlace_greedy_scanline_mmx (GstDeinterlaceMethodGreedyL * self,
+    const guint8 * m0, const guint8 * t1,
+    const guint8 * b1, const guint8 * m2, guint8 * output, gint width)
 {
   mmx_t MaxComb;
   mmx_t ShiftMask;
@@ -233,16 +232,15 @@ deinterlace_greedy_packed422_scanline_mmx (GstDeinterlaceMethodGreedyL * self,
   }
   emms ();
   if (width > 0)
-    deinterlace_greedy_packed422_scanline_c (self, m0, t1, b1, m2, output,
-        width);
+    deinterlace_greedy_scanline_c (self, m0, t1, b1, m2, output, width);
 }
 
 #include "sse.h"
 
 static void
-deinterlace_greedy_packed422_scanline_mmxext (GstDeinterlaceMethodGreedyL *
-    self, uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2,
-    uint8_t * output, int width)
+deinterlace_greedy_scanline_mmxext (GstDeinterlaceMethodGreedyL *
+    self, const guint8 * m0, const guint8 * t1, const guint8 * b1,
+    const guint8 * m2, guint8 * output, gint width)
 {
   mmx_t MaxComb;
 
@@ -327,70 +325,80 @@ deinterlace_greedy_packed422_scanline_mmxext (GstDeinterlaceMethodGreedyL *
   emms ();
 
   if (width > 0)
-    deinterlace_greedy_packed422_scanline_c (self, m0, t1, b1, m2, output,
-        width);
+    deinterlace_greedy_scanline_c (self, m0, t1, b1, m2, output, width);
 }
 
 #endif
 
 static void
-deinterlace_frame_di_greedy (GstDeinterlaceMethod * d_method,
-    GstDeinterlace * object, GstBuffer * outbuf)
+deinterlace_frame_di_greedy_packed (GstDeinterlaceMethod * method,
+    const GstDeinterlaceField * history, guint history_count,
+    GstBuffer * outbuf)
 {
-  GstDeinterlaceMethodGreedyL *self =
-      GST_DEINTERLACE_METHOD_GREEDY_L (d_method);
+  GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (method);
   GstDeinterlaceMethodGreedyLClass *klass =
       GST_DEINTERLACE_METHOD_GREEDY_L_GET_CLASS (self);
-  int InfoIsOdd = 0;
-  int Line;
-  unsigned int Pitch = object->field_stride;
-  unsigned char *L1;            // ptr to Line1, of 3
-  unsigned char *L2;            // ptr to Line2, the weave line
-  unsigned char *L3;            // ptr to Line3
-
-  unsigned char *L2P;           // ptr to prev Line2
-  unsigned char *Dest = GST_BUFFER_DATA (outbuf);
+  gint InfoIsOdd = 0;
+  gint Line;
+  gint RowStride = method->row_stride[0];
+  gint FieldHeight = method->frame_height / 2;
+  gint Pitch = method->row_stride[0] * 2;
+  const guint8 *L1;             // ptr to Line1, of 3
+  const guint8 *L2;             // ptr to Line2, the weave line
+  const guint8 *L3;             // ptr to Line3
+  const guint8 *L2P;            // ptr to prev Line2
+  guint8 *Dest = GST_BUFFER_DATA (outbuf);
 
   // copy first even line no matter what, and the first odd line if we're
   // processing an EVEN field. (note diff from other deint rtns.)
 
-  if (object->field_history[object->history_count - 1].flags ==
-      PICTURE_INTERLACED_BOTTOM) {
+  if (history[history_count - 1].flags == PICTURE_INTERLACED_BOTTOM) {
     InfoIsOdd = 1;
 
-    L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
-    L2 = GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
+    L1 = GST_BUFFER_DATA (history[history_count - 2].buf);
+    if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
+      L1 += RowStride;
+
+    L2 = GST_BUFFER_DATA (history[history_count - 1].buf);
+    if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
+      L2 += RowStride;
+
     L3 = L1 + Pitch;
-    L2P =
-        GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
+    L2P = GST_BUFFER_DATA (history[history_count - 3].buf);
+    if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
+      L2P += RowStride;
 
     // copy first even line
-    oil_memcpy (Dest, L1, object->row_stride);
-    Dest += object->row_stride;
+    oil_memcpy (Dest, L1, RowStride);
+    Dest += RowStride;
   } else {
     InfoIsOdd = 0;
-    L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
-    L2 = GST_BUFFER_DATA (object->field_history[object->history_count -
-            1].buf) + Pitch;
+    L1 = GST_BUFFER_DATA (history[history_count - 2].buf);
+    if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
+      L1 += RowStride;
+
+    L2 = GST_BUFFER_DATA (history[history_count - 1].buf) + Pitch;
+    if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
+      L2 += RowStride;
+
     L3 = L1 + Pitch;
-    L2P =
-        GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf) +
-        Pitch;
+    L2P = GST_BUFFER_DATA (history[history_count - 3].buf) + Pitch;
+    if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
+      L2P += RowStride;
 
     // copy first even line
-    oil_memcpy (Dest, GST_BUFFER_DATA (object->field_history[0].buf),
-        object->row_stride);
-    Dest += object->row_stride;
+    oil_memcpy (Dest, GST_BUFFER_DATA (history[0].buf), RowStride);
+    Dest += RowStride;
     // then first odd line
-    oil_memcpy (Dest, L1, object->row_stride);
-    Dest += object->row_stride;
+    oil_memcpy (Dest, L1, RowStride);
+    Dest += RowStride;
   }
 
-  for (Line = 0; Line < (object->field_height - 1); ++Line) {
-    klass->scanline (self, L2, L1, L3, L2P, Dest, object->row_stride);
-    Dest += object->row_stride;
-    oil_memcpy (Dest, L3, object->row_stride);
-    Dest += object->row_stride;
+  for (Line = 0; Line < (FieldHeight - 1); ++Line) {
+    klass->scanline (self, L2, L1, L3, L2P, Dest, RowStride);
+    Dest += RowStride;
+    oil_memcpy (Dest, L3, RowStride);
+    Dest += RowStride;
 
     L1 += Pitch;
     L2 += Pitch;
@@ -399,18 +407,17 @@ deinterlace_frame_di_greedy (GstDeinterlaceMethod * d_method,
   }
 
   if (InfoIsOdd) {
-    oil_memcpy (Dest, L2, object->row_stride);
+    oil_memcpy (Dest, L2, RowStride);
   }
 }
 
-
 G_DEFINE_TYPE (GstDeinterlaceMethodGreedyL, gst_deinterlace_method_greedy_l,
     GST_TYPE_DEINTERLACE_METHOD);
 
 enum
 {
-  ARG_0,
-  ARG_MAX_COMB
+  PROP_0,
+  PROP_MAX_COMB
 };
 
 static void
@@ -420,7 +427,7 @@ gst_deinterlace_method_greedy_l_set_property (GObject * object, guint prop_id,
   GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (object);
 
   switch (prop_id) {
-    case ARG_MAX_COMB:
+    case PROP_MAX_COMB:
       self->max_comb = g_value_get_uint (value);
       break;
     default:
@@ -435,7 +442,7 @@ gst_deinterlace_method_greedy_l_get_property (GObject * object, guint prop_id,
   GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (object);
 
   switch (prop_id) {
-    case ARG_MAX_COMB:
+    case PROP_MAX_COMB:
       g_value_set_uint (value, self->max_comb);
       break;
     default:
@@ -456,28 +463,30 @@ gst_deinterlace_method_greedy_l_class_init (GstDeinterlaceMethodGreedyLClass *
   gobject_class->set_property = gst_deinterlace_method_greedy_l_set_property;
   gobject_class->get_property = gst_deinterlace_method_greedy_l_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_MAX_COMB,
+  g_object_class_install_property (gobject_class, PROP_MAX_COMB,
       g_param_spec_uint ("max-comb",
           "Max comb",
           "Max Comb", 0, 255, 15, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
       );
 
   dim_class->fields_required = 4;
-  dim_class->deinterlace_frame = deinterlace_frame_di_greedy;
   dim_class->name = "Motion Adaptive: Simple Detection";
   dim_class->nick = "greedyl";
   dim_class->latency = 1;
 
+  dim_class->deinterlace_frame_yuy2 = deinterlace_frame_di_greedy_packed;
+  dim_class->deinterlace_frame_yvyu = deinterlace_frame_di_greedy_packed;
+
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
-    klass->scanline = deinterlace_greedy_packed422_scanline_mmxext;
+    klass->scanline = deinterlace_greedy_scanline_mmxext;
   } else if (cpu_flags & OIL_IMPL_FLAG_MMX) {
-    klass->scanline = deinterlace_greedy_packed422_scanline_mmx;
+    klass->scanline = deinterlace_greedy_scanline_mmx;
   } else {
-    klass->scanline = deinterlace_greedy_packed422_scanline_c;
+    klass->scanline = deinterlace_greedy_scanline_c;
   }
 #else
-  klass->scanline = deinterlace_greedy_packed422_scanline_c;
+  klass->scanline = deinterlace_greedy_scanline_c;
 #endif
 }
 
index 40aa00349428b2e101841dba78037fe875fec8b2..52edfebb12d6bc7acdd07eb08a19202e788376ff 100644 (file)
@@ -2,7 +2,7 @@
  *
  * GStreamer
  * Copyright (c) 2001 Tom Barry.  All rights reserved.
- * Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <slomo@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
@@ -15,7 +15,7 @@
  * 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
+ * License aglong with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 #include "x86-64_macros.inc"
 
 static void
-FUNCT_NAME (GstDeinterlaceMethodGreedyH *self, uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P,
-    uint8_t * Dest, int size)
+FUNCT_NAME (GstDeinterlaceMethodGreedyH *self, const guint8 * L1, const guint8 * L2, const guint8 * L3, const guint8 * L2P, guint8 * Dest, gint width)
 {
 
   // in tight loop some vars are accessed faster in local storage
-  int64_t YMask = 0x00ff00ff00ff00ffull;        // to keep only luma
-  int64_t UVMask = 0xff00ff00ff00ff00ull;       // to keep only chroma
-  int64_t ShiftMask = 0xfefefefefefefefeull;    // to avoid shifting chroma to luma
-  int64_t QW256 = 0x0100010001000100ull;        // 4 256's
-  int64_t MaxComb;
-  int64_t MotionThreshold;
-  int64_t MotionSense;
-  int64_t i;
-  long LoopCtr;
-  long oldbx;
-
-  int64_t QW256B;
-  int64_t LastAvg = 0;          //interp value from left qword
+  gint64 YMask = 0x00ff00ff00ff00ffull;        // to keep only luma
+  gint64 UVMask = 0xff00ff00ff00ff00ull;       // to keep only chroma
+  gint64 ShiftMask = 0xfefefefefefefefeull;    // to avoid shifting chroma to luma
+  gint64 QW256 = 0x0100010001000100ull;        // 4 256's
+  gint64 MaxComb;
+  gint64 MotionThreshold;
+  gint64 MotionSense;
+  gint64 i;
+  glong LoopCtr;
+  glong oldbx;
+
+  gint64 QW256B;
+  gint64 LastAvg = 0;          //interp value from left qword
+
   // FIXME: Use C implementation if the width is not a multiple of 4
   // Do something more optimal later
-  if (size % 8 != 0)
-    greedyDScaler_C (self, L1, L2, L3, L2P, Dest, size);
+  if (width % 4 != 0)
+    C_FUNCT (self, L1, L2, L3, L2P, Dest, width);
 
   // Set up our two parms that are actually evaluated for each pixel
   i = self->max_comb;
@@ -68,7 +67,7 @@ FUNCT_NAME (GstDeinterlaceMethodGreedyH *self, uint8_t * L1, uint8_t * L2, uint8
   i = 0xffffffff - 256;
   QW256B = i << 48 | i << 32 | i << 16 | i;     // save a couple instr on PMINSW instruct.
 
-  LoopCtr = size / 8 - 1;       // there are LineLength / 8 qwords per line but do 1 less, adj at end of loop
+  LoopCtr = width / 4 - 1;       // there are LineLength / 4 qwords per line but do 1 less, adj at end of loop
 
   // For ease of reading, the comments below assume that we're operating on an odd
   // field (i.e., that InfoIsOdd is true).  Assume the obvious for even lines..
index c72d73d03572e2b043da6e7b3b351421d584aada..49d4da0b4838977d6bc4cf3072f30abda981e937 100644 (file)
@@ -2,7 +2,7 @@
  *
  * GStreamer
  * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
- * Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <slomo@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
 #include "greedyhmacros.h"
 
 #include <stdlib.h>
-#include "_stdint.h"
 #include <string.h>
 
-#include "gst/gst.h"
+#include <gst/gst.h>
 #include "plugins.h"
 #include "gstdeinterlace.h"
 
@@ -54,41 +53,45 @@ typedef struct
   guint max_comb, motion_threshold, motion_sense;
 } GstDeinterlaceMethodGreedyH;
 
+typedef void (*ScanlineFunction) (GstDeinterlaceMethodGreedyH * self,
+    const guint8 * L2, const guint8 * L1, const guint8 * L3, const guint8 * L2P,
+    guint8 * Dest, gint width);
+
 typedef struct
 {
   GstDeinterlaceMethodClass parent_class;
-  void (*scanline) (GstDeinterlaceMethodGreedyH * self, uint8_t * L2,
-      uint8_t * L1, uint8_t * L3, uint8_t * L2P, uint8_t * Dest, int size);
+  ScanlineFunction scanline_yuy2;       /* This is for YVYU too */
 } GstDeinterlaceMethodGreedyHClass;
 
 static void
-greedyDScaler_C (GstDeinterlaceMethodGreedyH * self, uint8_t * L1, uint8_t * L2,
-    uint8_t * L3, uint8_t * L2P, uint8_t * Dest, int size)
+greedyh_scanline_yuy2_C (GstDeinterlaceMethodGreedyH * self, const guint8 * L1,
+    const guint8 * L2, const guint8 * L3, const guint8 * L2P, guint8 * Dest,
+    gint width)
 {
-  int Pos;
-  uint8_t l1_l, l1_1_l, l3_l, l3_1_l;
-  uint8_t l1_c, l1_1_c, l3_c, l3_1_c;
-  uint8_t avg_l, avg_c, avg_l_1, avg_c_1;
-  uint8_t avg_l__1 = 0, avg_c__1 = 0;
-  uint8_t avg_s_l, avg_s_c;
-  uint8_t avg_sc_l, avg_sc_c;
-  uint8_t best_l, best_c;
-  uint16_t mov_l;
-  uint8_t out_l, out_c;
-  uint8_t l2_l, l2_c, lp2_l, lp2_c;
-  uint8_t l2_l_diff, l2_c_diff, lp2_l_diff, lp2_c_diff;
-  uint8_t min_l, min_c, max_l, max_c;
+  gint Pos;
+  guint8 l1_l, l1_1_l, l3_l, l3_1_l;
+  guint8 l1_c, l1_1_c, l3_c, l3_1_c;
+  guint8 avg_l, avg_c, avg_l_1, avg_c_1;
+  guint8 avg_l__1 = 0, avg_c__1 = 0;
+  guint8 avg_s_l, avg_s_c;
+  guint8 avg_sc_l, avg_sc_c;
+  guint8 best_l, best_c;
+  guint16 mov_l;
+  guint8 out_l, out_c;
+  guint8 l2_l, l2_c, lp2_l, lp2_c;
+  guint8 l2_l_diff, l2_c_diff, lp2_l_diff, lp2_c_diff;
+  guint8 min_l, min_c, max_l, max_c;
   guint max_comb = self->max_comb;
   guint motion_sense = self->motion_sense;
   guint motion_threshold = self->motion_threshold;
 
-  for (Pos = 0; Pos < size; Pos += 2) {
+  for (Pos = 0; Pos < width; Pos++) {
     l1_l = L1[0];
     l1_c = L1[1];
     l3_l = L3[0];
     l3_c = L3[1];
 
-    if (Pos == size - 1) {
+    if (Pos == width - 1) {
       l1_1_l = l1_l;
       l1_1_c = l1_c;
       l3_1_l = l3_l;
@@ -207,7 +210,8 @@ greedyDScaler_C (GstDeinterlaceMethodGreedyH * self, uint8_t * L1, uint8_t * L2,
 
 #define IS_MMXEXT
 #define SIMD_TYPE MMXEXT
-#define FUNCT_NAME greedyDScaler_MMXEXT
+#define C_FUNCT greedyh_scanline_yuy2_C
+#define FUNCT_NAME greedyh_scanline_yuy2_MMXEXT
 #include "greedyh.asm"
 #undef SIMD_TYPE
 #undef IS_MMXEXT
@@ -215,7 +219,7 @@ greedyDScaler_C (GstDeinterlaceMethodGreedyH * self, uint8_t * L1, uint8_t * L2,
 
 #define IS_3DNOW
 #define SIMD_TYPE 3DNOW
-#define FUNCT_NAME greedyDScaler_3DNOW
+#define FUNCT_NAME greedyh_scanline_yuy2_3DNOW
 #include "greedyh.asm"
 #undef SIMD_TYPE
 #undef IS_3DNOW
@@ -223,74 +227,95 @@ greedyDScaler_C (GstDeinterlaceMethodGreedyH * self, uint8_t * L1, uint8_t * L2,
 
 #define IS_MMX
 #define SIMD_TYPE MMX
-#define FUNCT_NAME greedyDScaler_MMX
+#define FUNCT_NAME greedyh_scanline_yuy2_MMX
 #include "greedyh.asm"
 #undef SIMD_TYPE
 #undef IS_MMX
 #undef FUNCT_NAME
+#undef C_FUNCT
 
 #endif
 
 static void
-deinterlace_frame_di_greedyh (GstDeinterlaceMethod * d_method,
-    GstDeinterlace * object, GstBuffer * outbuf)
+deinterlace_frame_di_greedyh_packed (GstDeinterlaceMethod * method,
+    const GstDeinterlaceField * history, guint history_count,
+    GstBuffer * outbuf)
 {
-  GstDeinterlaceMethodGreedyH *self =
-      GST_DEINTERLACE_METHOD_GREEDY_H (d_method);
+  GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method);
   GstDeinterlaceMethodGreedyHClass *klass =
       GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self);
-  int InfoIsOdd = 0;
-  int Line;
-  unsigned int Pitch = object->field_stride;
-
-  unsigned char *L1;            // ptr to Line1, of 3
-  unsigned char *L2;            // ptr to Line2, the weave line
-  unsigned char *L3;            // ptr to Line3
-
-  unsigned char *L2P;           // ptr to prev Line2
-  unsigned char *Dest = GST_BUFFER_DATA (outbuf);
+  gint InfoIsOdd = 0;
+  gint Line;
+  gint RowStride = method->row_stride[0];
+  gint FieldHeight = method->frame_height / 2;
+  gint Pitch = method->row_stride[0] * 2;
+  const guint8 *L1;             // ptr to Line1, of 3
+  const guint8 *L2;             // ptr to Line2, the weave line
+  const guint8 *L3;             // ptr to Line3
+  const guint8 *L2P;            // ptr to prev Line2
+  guint8 *Dest = GST_BUFFER_DATA (outbuf);
+  ScanlineFunction scanline;
+
+  switch (method->format) {
+    case GST_VIDEO_FORMAT_YUY2:
+    case GST_VIDEO_FORMAT_YVYU:
+      scanline = klass->scanline_yuy2;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+  }
 
   // copy first even line no matter what, and the first odd line if we're
   // processing an EVEN field. (note diff from other deint rtns.)
 
-  if (object->field_history[object->history_count - 1].flags ==
-      PICTURE_INTERLACED_BOTTOM) {
+  if (history[history_count - 1].flags == PICTURE_INTERLACED_BOTTOM) {
     InfoIsOdd = 1;
 
-    L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
-    L2 = GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
+    L1 = GST_BUFFER_DATA (history[history_count - 2].buf);
+    if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
+      L1 += RowStride;
+
+    L2 = GST_BUFFER_DATA (history[history_count - 1].buf);
+    if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
+      L2 += RowStride;
+
     L3 = L1 + Pitch;
-    L2P =
-        GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
+    L2P = GST_BUFFER_DATA (history[history_count - 3].buf);
+    if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
+      L2P += RowStride;
 
     // copy first even line
-    oil_memcpy (Dest, L1, object->row_stride);
-    Dest += object->row_stride;
+    oil_memcpy (Dest, L1, RowStride);
+    Dest += RowStride;
   } else {
     InfoIsOdd = 0;
-    L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
-    L2 = GST_BUFFER_DATA (object->field_history[object->history_count -
-            1].buf) + Pitch;
+    L1 = GST_BUFFER_DATA (history[history_count - 2].buf);
+    if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
+      L1 += RowStride;
+
+    L2 = GST_BUFFER_DATA (history[history_count - 1].buf) + Pitch;
+    if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
+      L2 += RowStride;
+
     L3 = L1 + Pitch;
-    L2P =
-        GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf) +
-        Pitch;
+    L2P = GST_BUFFER_DATA (history[history_count - 3].buf) + Pitch;
+    if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
+      L2P += RowStride;
 
     // copy first even line
-    oil_memcpy (Dest,
-        GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf),
-        object->row_stride);
-    Dest += object->row_stride;
+    oil_memcpy (Dest, L1, RowStride);
+    Dest += RowStride;
     // then first odd line
-    oil_memcpy (Dest, L1, object->row_stride);
-    Dest += object->row_stride;
+    oil_memcpy (Dest, L1, RowStride);
+    Dest += RowStride;
   }
 
-  for (Line = 0; Line < (object->field_height - 1); ++Line) {
-    klass->scanline (self, L1, L2, L3, L2P, Dest, object->row_stride);
-    Dest += object->row_stride;
-    oil_memcpy (Dest, L3, object->row_stride);
-    Dest += object->row_stride;
+  for (Line = 0; Line < (FieldHeight - 1); ++Line) {
+    scanline (self, L1, L2, L3, L2P, Dest, RowStride);
+    Dest += RowStride;
+    oil_memcpy (Dest, L3, RowStride);
+    Dest += RowStride;
 
     L1 += Pitch;
     L2 += Pitch;
@@ -299,7 +324,7 @@ deinterlace_frame_di_greedyh (GstDeinterlaceMethod * d_method,
   }
 
   if (InfoIsOdd) {
-    oil_memcpy (Dest, L2, object->row_stride);
+    oil_memcpy (Dest, L2, RowStride);
   }
 }
 
@@ -308,10 +333,10 @@ G_DEFINE_TYPE (GstDeinterlaceMethodGreedyH, gst_deinterlace_method_greedy_h,
 
 enum
 {
-  ARG_0,
-  ARG_MAX_COMB,
-  ARG_MOTION_THRESHOLD,
-  ARG_MOTION_SENSE
+  PROP_0,
+  PROP_MAX_COMB,
+  PROP_MOTION_THRESHOLD,
+  PROP_MOTION_SENSE
 };
 
 static void
@@ -321,13 +346,13 @@ gst_deinterlace_method_greedy_h_set_property (GObject * object, guint prop_id,
   GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (object);
 
   switch (prop_id) {
-    case ARG_MAX_COMB:
+    case PROP_MAX_COMB:
       self->max_comb = g_value_get_uint (value);
       break;
-    case ARG_MOTION_THRESHOLD:
+    case PROP_MOTION_THRESHOLD:
       self->motion_threshold = g_value_get_uint (value);
       break;
-    case ARG_MOTION_SENSE:
+    case PROP_MOTION_SENSE:
       self->motion_sense = g_value_get_uint (value);
       break;
     default:
@@ -342,13 +367,13 @@ gst_deinterlace_method_greedy_h_get_property (GObject * object, guint prop_id,
   GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (object);
 
   switch (prop_id) {
-    case ARG_MAX_COMB:
+    case PROP_MAX_COMB:
       g_value_set_uint (value, self->max_comb);
       break;
-    case ARG_MOTION_THRESHOLD:
+    case PROP_MOTION_THRESHOLD:
       g_value_set_uint (value, self->motion_threshold);
       break;
-    case ARG_MOTION_SENSE:
+    case PROP_MOTION_SENSE:
       g_value_set_uint (value, self->motion_sense);
       break;
     default:
@@ -369,20 +394,20 @@ gst_deinterlace_method_greedy_h_class_init (GstDeinterlaceMethodGreedyHClass *
   gobject_class->set_property = gst_deinterlace_method_greedy_h_set_property;
   gobject_class->get_property = gst_deinterlace_method_greedy_h_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_MAX_COMB,
+  g_object_class_install_property (gobject_class, PROP_MAX_COMB,
       g_param_spec_uint ("max-comb",
           "Max comb",
           "Max Comb", 0, 255, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
       );
 
-  g_object_class_install_property (gobject_class, ARG_MOTION_THRESHOLD,
+  g_object_class_install_property (gobject_class, PROP_MOTION_THRESHOLD,
       g_param_spec_uint ("motion-threshold",
           "Motion Threshold",
           "Motion Threshold",
           0, 255, 25, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
       );
 
-  g_object_class_install_property (gobject_class, ARG_MOTION_SENSE,
+  g_object_class_install_property (gobject_class, PROP_MOTION_SENSE,
       g_param_spec_uint ("motion-sense",
           "Motion Sense",
           "Motion Sense",
@@ -390,23 +415,25 @@ gst_deinterlace_method_greedy_h_class_init (GstDeinterlaceMethodGreedyHClass *
       );
 
   dim_class->fields_required = 4;
-  dim_class->deinterlace_frame = deinterlace_frame_di_greedyh;
   dim_class->name = "Motion Adaptive: Advanced Detection";
   dim_class->nick = "greedyh";
   dim_class->latency = 1;
 
+  dim_class->deinterlace_frame_yuy2 = deinterlace_frame_di_greedyh_packed;
+  dim_class->deinterlace_frame_yvyu = deinterlace_frame_di_greedyh_packed;
+
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
-    klass->scanline = greedyDScaler_MMXEXT;
+    klass->scanline_yuy2 = greedyh_scanline_yuy2_MMXEXT;
   } else if (cpu_flags & OIL_IMPL_FLAG_3DNOW) {
-    klass->scanline = greedyDScaler_3DNOW;
+    klass->scanline_yuy2 = greedyh_scanline_yuy2_3DNOW;
   } else if (cpu_flags & OIL_IMPL_FLAG_MMX) {
-    klass->scanline = greedyDScaler_MMX;
+    klass->scanline_yuy2 = greedyh_scanline_yuy2_MMX;
   } else {
-    klass->scanline = greedyDScaler_C;
+    klass->scanline_yuy2 = greedyh_scanline_yuy2_C;
   }
 #else
-  klass->scanline = greedyDScaler_C;
+  klass->scanline_yuy2 = greedyh_scanline_yuy2_C;
 #endif
 }
 
index fe57dcb8e4a84cc5756574f813cffadca17b7e3f..f354481f8ad38880b98a26f54c71d1df5841d33b 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2002 Billy Biggs <vektor@dumbterm.net>.
- * Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <slomo@collabora.co.uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,6 @@
 # include "config.h"
 #endif
 
-#include "_stdint.h"
 #include "gstdeinterlace.h"
 #include <string.h>
 
 GType gst_deinterlace_method_linear_get_type (void);
 
 typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodLinear;
-
 typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodLinearClass;
 
 static void
-deinterlace_scanline_linear_c (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_linear_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const guint8 * s1, const guint8 * s2, gint size)
 {
   gint i;
 
-  width *= 2;
-  for (i = 0; i < width; i++)
-    out[i] = (scanlines->t0[i] + scanlines->b0[i]) / 2;
+  for (i = 0; i < size; i++)
+    out[i] = (s1[i] + s2[i]) / 2;
+}
+
+static void
+deinterlace_scanline_linear_packed_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_c (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[0]);
 }
 
 #ifdef BUILD_X86_ASM
 #include "mmx.h"
 static void
-deinterlace_scanline_linear_mmx (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_linear_mmx (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const guint8 * bot, const guint8 * top, gint size)
 {
   const mmx_t shiftmask = { 0xfefffefffefffeffULL };    /* To avoid shifting chroma to luma. */
   int i;
-  guint8 *bot = scanlines->b0, *top = scanlines->t0;
 
-  for (i = width / 16; i; --i) {
+  for (i = size / 32; i; --i) {
     movq_m2r (*bot, mm0);
     movq_m2r (*top, mm1);
     movq_m2r (*(bot + 8), mm2);
@@ -105,9 +107,9 @@ deinterlace_scanline_linear_mmx (GstDeinterlaceMethod * self,
     top += 32;
     bot += 32;
   }
-  width = (width & 0xf);
+  size = (size & 0x1f);
 
-  for (i = width / 4; i; --i) {
+  for (i = size / 8; i; --i) {
     movq_m2r (*bot, mm0);
     movq_m2r (*top, mm1);
     pand_m2r (shiftmask, mm0);
@@ -120,26 +122,32 @@ deinterlace_scanline_linear_mmx (GstDeinterlaceMethod * self,
     top += 8;
     bot += 8;
   }
-  width = width & 0x7;
+  emms ();
+
+  size = size & 0xf;
 
   /* Handle last few pixels. */
-  for (i = width * 2; i; --i) {
+  for (i = size; i; --i) {
     *out++ = ((*top++) + (*bot++)) >> 1;
   }
+}
 
-  emms ();
+static void
+deinterlace_scanline_linear_packed_mmx (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_mmx (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[0]);
 }
 
 #include "sse.h"
 static void
-deinterlace_scanline_linear_mmxext (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_linear_mmxext (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const guint8 * bot, const guint8 * top, gint size)
 {
   gint i;
-  guint8 *bot = scanlines->b0, *top = scanlines->t0;
 
-  for (i = width / 16; i; --i) {
+  for (i = size / 32; i; --i) {
     movq_m2r (*bot, mm0);
     movq_m2r (*top, mm1);
     movq_m2r (*(bot + 8), mm2);
@@ -160,9 +168,9 @@ deinterlace_scanline_linear_mmxext (GstDeinterlaceMethod * self,
     top += 32;
     bot += 32;
   }
-  width = (width & 0xf);
+  size = (size & 0x1f);
 
-  for (i = width / 4; i; --i) {
+  for (i = size / 8; i; --i) {
     movq_m2r (*bot, mm0);
     movq_m2r (*top, mm1);
     pavgb_r2r (mm1, mm0);
@@ -171,14 +179,22 @@ deinterlace_scanline_linear_mmxext (GstDeinterlaceMethod * self,
     top += 8;
     bot += 8;
   }
-  width = width & 0x7;
+  emms ();
+
+  size = size & 0xf;
 
   /* Handle last few pixels. */
-  for (i = width * 2; i; --i) {
+  for (i = size; i; --i) {
     *out++ = ((*top++) + (*bot++)) >> 1;
   }
+}
 
-  emms ();
+static void
+deinterlace_scanline_linear_packed_mmxext (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_mmxext (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[0]);
 }
 
 #endif
@@ -202,13 +218,20 @@ gst_deinterlace_method_linear_class_init (GstDeinterlaceMethodLinearClass *
   dim_class->nick = "linear";
   dim_class->latency = 0;
 
-  dism_class->interpolate_scanline = deinterlace_scanline_linear_c;
+  dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_linear_packed_c;
+  dism_class->interpolate_scanline_yvyu = deinterlace_scanline_linear_packed_c;
 
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
-    dism_class->interpolate_scanline = deinterlace_scanline_linear_mmxext;
-  } else if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
-    dism_class->interpolate_scanline = deinterlace_scanline_linear_mmx;
+    dism_class->interpolate_scanline_yuy2 =
+        deinterlace_scanline_linear_packed_mmxext;
+    dism_class->interpolate_scanline_yvyu =
+        deinterlace_scanline_linear_packed_mmxext;
+  } else if (cpu_flags & OIL_IMPL_FLAG_MMX) {
+    dism_class->interpolate_scanline_yuy2 =
+        deinterlace_scanline_linear_packed_mmx;
+    dism_class->interpolate_scanline_yvyu =
+        deinterlace_scanline_linear_packed_mmx;
   }
 #endif
 }
index 1a41105cd9d3deaefdad8c0b27aaf130c9b008fd..c8f0fc566c60af90921a1ae9ae9fadb21f83fe75 100644 (file)
@@ -4,7 +4,7 @@
  * sources.
  *
  * Copyright (C) 2002 Billy Biggs <vektor@dumbterm.net>.
- * Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <slomo@collabora.co.uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,6 @@
 # include "config.h"
 #endif
 
-#include "_stdint.h"
 #include "gstdeinterlace.h"
 #include <string.h>
 
 GType gst_deinterlace_method_linear_blend_get_type (void);
 
 typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodLinearBlend;
-
 typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodLinearBlendClass;
 
-
 static inline void
-deinterlace_scanline_linear_blend_c (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_linear_blend_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const guint8 * t0, const guint8 * b0, const guint8 * m1,
+    gint size)
 {
-  guint8 *t0 = scanlines->t0;
-  guint8 *b0 = scanlines->b0;
-  guint8 *m1 = scanlines->m1;
-
-  width *= 2;
-
-  while (width--) {
+  while (size--) {
     *out++ = (*t0++ + *b0++ + (*m1++ << 1)) >> 2;
   }
 }
 
-static inline void
-deinterlace_scanline_linear_blend2_c (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+static void
+deinterlace_scanline_linear_blend_packed_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
 {
-  guint8 *m0 = scanlines->m0;
-  guint8 *t1 = scanlines->t1;
-  guint8 *b1 = scanlines->b1;
+  deinterlace_scanline_linear_blend_c (self, out, scanlines->t0, scanlines->b0,
+      scanlines->m1, self->parent.row_stride[0]);
+}
 
-  width *= 2;
-  while (width--) {
+static inline void
+deinterlace_scanline_linear_blend2_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const guint8 * m0, const guint8 * t1, const guint8 * b1,
+    gint size)
+{
+  while (size--) {
     *out++ = (*t1++ + *b1++ + (*m0++ << 1)) >> 2;
   }
 }
 
+static void
+deinterlace_scanline_linear_blend2_packed_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend2_c (self, out, scanlines->m0, scanlines->t1,
+      scanlines->b1, self->parent.row_stride[0]);
+}
+
 #ifdef BUILD_X86_ASM
 #include "mmx.h"
 static inline void
-deinterlace_scanline_linear_blend_mmx (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_linear_blend_mmx (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const guint8 * t0, const guint8 * b0, const guint8 * m1,
+    gint size)
 {
-  guint8 *t0 = scanlines->t0;
-  guint8 *b0 = scanlines->b0;
-  guint8 *m1 = scanlines->m1;
   gint i;
 
-  // Get width in bytes.
-  width *= 2;
-  i = width / 8;
-  width -= i * 8;
+  i = size / 8;
+  size -= i * 8;
 
   pxor_r2r (mm7, mm7);
   while (i--) {
@@ -134,26 +131,29 @@ deinterlace_scanline_linear_blend_mmx (GstDeinterlaceMethod * self,
     b0 += 8;
     m1 += 8;
   }
-  while (width--) {
+  emms ();
+  while (size--) {
     *out++ = (*t0++ + *b0++ + (*m1++ << 1)) >> 2;
   }
-  emms ();
+}
+
+static void
+deinterlace_scanline_linear_blend_packed_mmx (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend_mmx (self, out, scanlines->t0,
+      scanlines->b0, scanlines->m1, self->parent.row_stride[0]);
 }
 
 static inline void
-deinterlace_scanline_linear_blend2_mmx (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_linear_blend2_mmx (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const guint8 * m0, const guint8 * t1, const guint8 * b1,
+    gint size)
 {
-  guint8 *m0 = scanlines->m0;
-  guint8 *t1 = scanlines->t1;
-  guint8 *b1 = scanlines->b1;
   gint i;
 
-  // Get width in bytes.
-  width *= 2;
-  i = width / 8;
-  width -= i * 8;
+  i = size / 8;
+  size -= i * 8;
 
   pxor_r2r (mm7, mm7);
   while (i--) {
@@ -191,10 +191,19 @@ deinterlace_scanline_linear_blend2_mmx (GstDeinterlaceMethod * self,
     b1 += 8;
     m0 += 8;
   }
-  while (width--) {
+  emms ();
+
+  while (size--) {
     *out++ = (*t1++ + *b1++ + (*m0++ << 1)) >> 2;
   }
-  emms ();
+}
+
+static void
+deinterlace_scanline_linear_blend2_packed_mmx (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend2_mmx (self, out, scanlines->m0,
+      scanlines->t1, scanlines->b1, self->parent.row_stride[0]);
 }
 
 #endif
@@ -218,13 +227,23 @@ static void
   dim_class->nick = "linearblend";
   dim_class->latency = 0;
 
-  dism_class->interpolate_scanline = deinterlace_scanline_linear_blend_c;
-  dism_class->copy_scanline = deinterlace_scanline_linear_blend2_c;
+  dism_class->interpolate_scanline_yuy2 =
+      deinterlace_scanline_linear_blend_packed_c;
+  dism_class->interpolate_scanline_yvyu =
+      deinterlace_scanline_linear_blend_packed_c;
+  dism_class->copy_scanline_yuy2 = deinterlace_scanline_linear_blend2_packed_c;
+  dism_class->copy_scanline_yvyu = deinterlace_scanline_linear_blend2_packed_c;
 
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMX) {
-    dism_class->interpolate_scanline = deinterlace_scanline_linear_blend_mmx;
-    dism_class->copy_scanline = deinterlace_scanline_linear_blend2_mmx;
+    dism_class->interpolate_scanline_yuy2 =
+        deinterlace_scanline_linear_blend_packed_mmx;
+    dism_class->interpolate_scanline_yvyu =
+        deinterlace_scanline_linear_blend_packed_mmx;
+    dism_class->copy_scanline_yuy2 =
+        deinterlace_scanline_linear_blend2_packed_mmx;
+    dism_class->copy_scanline_yvyu =
+        deinterlace_scanline_linear_blend2_packed_mmx;
   }
 #endif
 }
index a7bca169f697bd30310b99ca8637234a6bbf75be..bf567ac544a7ff50214c0762d6ccd06dd54f4b7d 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * Double lines
- * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,6 @@
 # include "config.h"
 #endif
 
-#include "_stdint.h"
 #include "gstdeinterlace.h"
 #include <string.h>
 
 GType gst_deinterlace_method_scaler_bob_get_type (void);
 
 typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodScalerBob;
-
 typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodScalerBobClass;
 
-
 static void
-deinterlace_scanline_scaler_bob (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_scaler_bob_packed (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
 {
-  oil_memcpy (out, scanlines->t0, parent->row_stride);
+  oil_memcpy (out, scanlines->t0, self->parent.row_stride[0]);
 }
 
 G_DEFINE_TYPE (GstDeinterlaceMethodScalerBob, gst_deinterlace_method_scaler_bob,
@@ -65,7 +61,10 @@ gst_deinterlace_method_scaler_bob_class_init (GstDeinterlaceMethodScalerBobClass
   dim_class->nick = "scalerbob";
   dim_class->latency = 0;
 
-  dism_class->interpolate_scanline = deinterlace_scanline_scaler_bob;
+  dism_class->interpolate_scanline_yuy2 =
+      deinterlace_scanline_scaler_bob_packed;
+  dism_class->interpolate_scanline_yvyu =
+      deinterlace_scanline_scaler_bob_packed;
 }
 
 static void
index cab6fafd563a5350801255883199ad5455b12902..36412386df15cef4a23e9b4d87129f18660597b9 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
- * Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <slomo@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
 #endif
 
 #include <stdlib.h>
-#include "_stdint.h"
 #include <string.h>
 
-#include "gst/gst.h"
+#include <gst/gst.h>
 #include "gstdeinterlace.h"
 #include "plugins.h"
 
@@ -51,26 +50,19 @@ typedef struct
   gboolean strange_bob;
 } GstDeinterlaceMethodTomsMoComp;
 
-typedef struct
-{
-  GstDeinterlaceMethodClass parent_class;
-} GstDeinterlaceMethodTomsMoCompClass;
+typedef GstDeinterlaceMethodClass GstDeinterlaceMethodTomsMoCompClass;
 
-static int
-Fieldcopy (void *dest, const void *src, size_t count,
-    int rows, int dst_pitch, int src_pitch)
+static void
+Fieldcopy (guint8 * dest, const guint8 * src, gint count,
+    gint rows, gint dst_pitch, gint src_pitch)
 {
-  unsigned char *pDest = (unsigned char *) dest;
-  unsigned char *pSrc = (unsigned char *) src;
-
-  int i;
+  gint i;
 
   for (i = 0; i < rows; i++) {
-    oil_memcpy (pDest, pSrc, count);
-    pSrc += src_pitch;
-    pDest += dst_pitch;
+    oil_memcpy (dest, src, count);
+    src += src_pitch;
+    dest += dst_pitch;
   }
-  return 0;
 }
 
 #define USE_FOR_DSCALER
@@ -119,9 +111,9 @@ G_DEFINE_TYPE (GstDeinterlaceMethodTomsMoComp,
 
 enum
 {
-  ARG_0,
-  ARG_SEARCH_EFFORT,
-  ARG_STRANGE_BOB
+  PROP_0,
+  PROP_SEARCH_EFFORT,
+  PROP_STRANGE_BOB
 };
 
 static void
@@ -132,10 +124,10 @@ gst_deinterlace_method_tomsmocomp_set_property (GObject * object, guint prop_id,
       GST_DEINTERLACE_METHOD_TOMSMOCOMP (object);
 
   switch (prop_id) {
-    case ARG_SEARCH_EFFORT:
+    case PROP_SEARCH_EFFORT:
       self->search_effort = g_value_get_uint (value);
       break;
-    case ARG_STRANGE_BOB:
+    case PROP_STRANGE_BOB:
       self->strange_bob = g_value_get_boolean (value);
       break;
     default:
@@ -151,10 +143,10 @@ gst_deinterlace_method_tomsmocomp_get_property (GObject * object, guint prop_id,
       GST_DEINTERLACE_METHOD_TOMSMOCOMP (object);
 
   switch (prop_id) {
-    case ARG_SEARCH_EFFORT:
+    case PROP_SEARCH_EFFORT:
       g_value_set_uint (value, self->search_effort);
       break;
-    case ARG_STRANGE_BOB:
+    case PROP_STRANGE_BOB:
       g_value_set_boolean (value, self->strange_bob);
       break;
     default:
@@ -175,13 +167,13 @@ static void
   gobject_class->set_property = gst_deinterlace_method_tomsmocomp_set_property;
   gobject_class->get_property = gst_deinterlace_method_tomsmocomp_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_SEARCH_EFFORT,
+  g_object_class_install_property (gobject_class, PROP_SEARCH_EFFORT,
       g_param_spec_uint ("search-effort",
           "Search Effort",
           "Search Effort", 0, 27, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
       );
 
-  g_object_class_install_property (gobject_class, ARG_STRANGE_BOB,
+  g_object_class_install_property (gobject_class, PROP_STRANGE_BOB,
       g_param_spec_boolean ("strange-bob",
           "Strange Bob",
           "Use strange bob", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
@@ -194,16 +186,21 @@ static void
 
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
-    dim_class->deinterlace_frame = tomsmocompDScaler_MMXEXT;
+    dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_MMXEXT;
+    dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_MMXEXT;
   } else if (cpu_flags & OIL_IMPL_FLAG_3DNOW) {
-    dim_class->deinterlace_frame = tomsmocompDScaler_3DNOW;
+    dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_3DNOW;
+    dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_3DNOW;
   } else if (cpu_flags & OIL_IMPL_FLAG_MMX) {
-    dim_class->deinterlace_frame = tomsmocompDScaler_MMX;
+    dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_MMX;
+    dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_MMX;
   } else {
-    dim_class->deinterlace_frame = tomsmocompDScaler_C;
+    dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_C;
+    dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_C;
   }
 #else
-  dim_class->deinterlace_frame = tomsmocompDScaler_C;
+  dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_C;
+  dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_C;
 #endif
 }
 
index 358a9bd88f95810673e3515f77e260dd80b4e840..23903b3bbb5f881c80f5bebccb68f0ad7248b335 100644 (file)
 #define SEFUNC(x) Search_Effort_C_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight)
 #endif
 
-static void FUNCT_NAME(GstDeinterlaceMethod *d_method, GstDeinterlace* object, GstBuffer *outbuf)
+static void FUNCT_NAME(GstDeinterlaceMethod *d_method, const GstDeinterlaceField* history, guint history_count, GstBuffer *outbuf)
 {
   GstDeinterlaceMethodTomsMoComp *self = GST_DEINTERLACE_METHOD_TOMSMOCOMP (d_method);
-  long SearchEffort = self->search_effort;
-  int UseStrangeBob = self->strange_bob;
-  int IsOdd;
-  const unsigned char *pWeaveSrc;
-  const unsigned char *pWeaveSrcP;
-  unsigned char *pWeaveDest;
-  const unsigned char *pCopySrc;
-  const unsigned char *pCopySrcP;
-  unsigned char *pCopyDest;
-  int src_pitch;
-  int dst_pitch;
-  int rowsize;
-  int FldHeight;
+  glong SearchEffort = self->search_effort;
+  gint UseStrangeBob = self->strange_bob;
+  gint IsOdd;
+  const guint8 *pWeaveSrc;
+  const guint8 *pWeaveSrcP;
+  guint8 *pWeaveDest;
+  const guint8 *pCopySrc;
+  const guint8 *pCopySrcP;
+  guint8 *pCopyDest;
+  gint src_pitch;
+  gint dst_pitch;
+  gint rowsize;
+  gint FldHeight;
 
   /* double stride do address just every odd/even scanline */
-  src_pitch = object->field_stride;
-  dst_pitch = object->row_stride;
-  rowsize   = object->row_stride;
-  FldHeight = object->field_height;
-
-  pCopySrc   = GST_BUFFER_DATA(object->field_history[object->history_count-1].buf);
-  pCopySrcP  = GST_BUFFER_DATA(object->field_history[object->history_count-3].buf);
-  pWeaveSrc  = GST_BUFFER_DATA(object->field_history[object->history_count-2].buf);  
-  pWeaveSrcP = GST_BUFFER_DATA(object->field_history[object->history_count-4].buf);
+  src_pitch = self->parent.row_stride[0]*2;
+  dst_pitch = self->parent.row_stride[0];
+  rowsize   = self->parent.row_stride[0];
+  FldHeight = self->parent.frame_height / 2;
+
+  pCopySrc   = GST_BUFFER_DATA(history[history_count-1].buf);
+  if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
+    pCopySrc += rowsize;
+  pCopySrcP  = GST_BUFFER_DATA(history[history_count-3].buf);
+  if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
+    pCopySrcP += rowsize;
+  pWeaveSrc  = GST_BUFFER_DATA(history[history_count-2].buf);  
+  if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
+    pWeaveSrc += rowsize;
+  pWeaveSrcP = GST_BUFFER_DATA(history[history_count-4].buf);
+  if (history[history_count - 4].flags & PICTURE_INTERLACED_BOTTOM)
+    pWeaveSrcP += rowsize;
 
   /* use bottom field and interlace top field */
-  if (object->field_history[object->history_count-2].flags == PICTURE_INTERLACED_BOTTOM) {
+  if (history[history_count-2].flags == PICTURE_INTERLACED_BOTTOM) {
     IsOdd      = 1;
 
     // if we have an odd field we copy an even field and weave an odd field
index b3ebaae1a5f829def61f4aeb1861153de632421b..e27859d71a4a72c2b9f1c201deb5e40444fea1b0 100644 (file)
@@ -3,7 +3,7 @@
  * GStreamer
  * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
  * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
- * Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <slomo@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
@@ -33,7 +33,6 @@
 # include "config.h"
 #endif
 
-#include "_stdint.h"
 #include "gstdeinterlace.h"
 #include <string.h>
 
@@ -62,16 +61,10 @@ typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodVFIRClass;
   * C implementation.
   */
 static inline void
-deinterlace_line_c (GstDeinterlaceMethod * self, GstDeinterlace * parent,
-    guint8 * dst, GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_c (guint8 * dst, const guint8 * lum_m4, const guint8 * lum_m3,
+    const guint8 * lum_m2, const guint8 * lum_m1, const guint8 * lum, gint size)
 {
   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];
@@ -89,18 +82,27 @@ deinterlace_line_c (GstDeinterlaceMethod * self, GstDeinterlace * parent,
   }
 }
 
+static void
+deinterlace_line_packed_c (GstDeinterlaceSimpleMethod * self, guint8 * dst,
+    const GstDeinterlaceScanlineData * scanlines)
+{
+  const guint8 *lum_m4 = scanlines->tt1;
+  const guint8 *lum_m3 = scanlines->t0;
+  const guint8 *lum_m2 = scanlines->m1;
+  const guint8 *lum_m1 = scanlines->b0;
+  const guint8 *lum = scanlines->bb1;
+  gint size = self->parent.row_stride[0];
+
+  deinterlace_c (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size);
+}
+
 #ifdef BUILD_X86_ASM
 #include "mmx.h"
 static void
-deinterlace_line_mmx (GstDeinterlaceMethod * self, GstDeinterlace * parent,
-    guint8 * dst, GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_mmx (guint8 * dst, const guint8 * lum_m4, const guint8 * lum_m3,
+    const guint8 * lum_m2, const guint8 * lum_m1, const guint8 * lum, gint size)
 {
   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;
@@ -109,7 +111,7 @@ deinterlace_line_mmx (GstDeinterlaceMethod * self, GstDeinterlace * parent,
   pxor_r2r (mm7, mm7);
   movq_m2r (rounder, mm6);
 
-  for (; width > 1; width -= 2) {
+  for (; size > 3; size -= 4) {
     movd_m2r (*lum_m4, mm0);
     movd_m2r (*lum_m3, mm1);
     movd_m2r (*lum_m2, mm2);
@@ -140,15 +142,22 @@ deinterlace_line_mmx (GstDeinterlaceMethod * self, GstDeinterlace * parent,
   emms ();
 
   /* Handle odd widths */
-  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);
-  }
+  if (size > 0)
+    deinterlace_c (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size);
+}
+
+static void
+deinterlace_line_packed_mmx (GstDeinterlaceSimpleMethod * self, guint8 * dst,
+    const GstDeinterlaceScanlineData * scanlines)
+{
+  const guint8 *lum_m4 = scanlines->tt1;
+  const guint8 *lum_m3 = scanlines->t0;
+  const guint8 *lum_m2 = scanlines->m1;
+  const guint8 *lum_m1 = scanlines->b0;
+  const guint8 *lum = scanlines->bb1;
+  gint size = self->parent.row_stride[0];
+
+  deinterlace_mmx (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size);
 }
 #endif
 
@@ -172,12 +181,15 @@ gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
 
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMX) {
-    dism_class->interpolate_scanline = deinterlace_line_mmx;
+    dism_class->interpolate_scanline_yuy2 = deinterlace_line_packed_mmx;
+    dism_class->interpolate_scanline_yvyu = deinterlace_line_packed_mmx;
   } else {
-    dism_class->interpolate_scanline = deinterlace_line_c;
+    dism_class->interpolate_scanline_yuy2 = deinterlace_line_packed_c;
+    dism_class->interpolate_scanline_yvyu = deinterlace_line_packed_c;
   }
 #else
-  dism_class->interpolate_scanline = deinterlace_line_c;
+  dism_class->interpolate_scanline_yuy2 = deinterlace_line_packed_c;
+  dism_class->interpolate_scanline_yvyu = deinterlace_line_packed_c;
 #endif
 }
 
index 430879a818354f219abe3c628caaf8d9797feb5a..16dcd6253eb6a21facc52c9140843c608327601d 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * Weave frames
  * Copyright (C) 2002 Billy Biggs <vektor@dumbterm.net>.
- * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,6 @@
 # include "config.h"
 #endif
 
-#include "_stdint.h"
 #include "gstdeinterlace.h"
 #include <string.h>
 
 GType gst_deinterlace_method_weave_get_type (void);
 
 typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodWeave;
-
 typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodWeaveClass;
 
-
 static void
-deinterlace_scanline_weave (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
 {
-  oil_memcpy (out, scanlines->m1, parent->row_stride);
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[0]);
 }
 
 static void
-copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace * parent,
-    guint8 * out, GstDeinterlaceScanlineData * scanlines, gint width)
+copy_scanline_packed (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
 {
-  oil_memcpy (out, scanlines->m0, parent->row_stride);
+  oil_memcpy (out, scanlines->m0, self->parent.row_stride[0]);
 }
 
 G_DEFINE_TYPE (GstDeinterlaceMethodWeave, gst_deinterlace_method_weave,
@@ -77,8 +73,9 @@ gst_deinterlace_method_weave_class_init (GstDeinterlaceMethodWeaveClass * klass)
   dim_class->nick = "weave";
   dim_class->latency = 0;
 
-  dism_class->interpolate_scanline = deinterlace_scanline_weave;
-  dism_class->copy_scanline = copy_scanline;
+  dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_yvyu = deinterlace_scanline_weave_packed;
+  dism_class->copy_scanline_yvyu = copy_scanline_packed;
 }
 
 static void
index e0b41d57eb285b3d5fd76da46b9d8d6794a470f6..e81a09c132e0780b09478d5b5b1a904117ad2977 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * Weave frames, bottom-field-first.
  * Copyright (C) 2003 Billy Biggs <vektor@dumbterm.net>.
- * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,6 @@
 # include "config.h"
 #endif
 
-#include "_stdint.h"
 #include "gstdeinterlace.h"
 #include <string.h>
 
 GType gst_deinterlace_method_weave_bff_get_type (void);
 
 typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodWeaveBFF;
-
 typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodWeaveBFFClass;
 
-
 static void
-deinterlace_scanline_weave (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
 {
-  oil_memcpy (out, scanlines->m1, parent->row_stride);
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[0]);
 }
 
 static void
-copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace * parent,
-    guint8 * out, GstDeinterlaceScanlineData * scanlines, gint width)
+copy_scanline_packed (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
 {
   /* FIXME: original code used m2 and m0 but this looks really bad */
   if (scanlines->bottom_field) {
-    oil_memcpy (out, scanlines->bb2, parent->row_stride);
+    oil_memcpy (out, scanlines->bb2, self->parent.row_stride[0]);
   } else {
-    oil_memcpy (out, scanlines->bb0, parent->row_stride);
+    oil_memcpy (out, scanlines->bb0, self->parent.row_stride[0]);
   }
 }
 
@@ -83,8 +79,10 @@ gst_deinterlace_method_weave_bff_class_init (GstDeinterlaceMethodWeaveBFFClass *
   dim_class->nick = "weavebff";
   dim_class->latency = 0;
 
-  dism_class->interpolate_scanline = deinterlace_scanline_weave;
-  dism_class->copy_scanline = copy_scanline;
+  dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_yvyu = deinterlace_scanline_weave_packed;
+  dism_class->copy_scanline_yuy2 = copy_scanline_packed;
+  dism_class->copy_scanline_yvyu = copy_scanline_packed;
 }
 
 static void
index c567a431c8cae1be3e9308ffb8ec5e41a4382075..1e91026e0db3fff2ad1820fe38f3b1767a461ab9 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * Weave frames, top-field-first.
  * Copyright (C) 2003 Billy Biggs <vektor@dumbterm.net>.
- * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2008,2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -29,7 +29,6 @@
 # include "config.h"
 #endif
 
-#include "_stdint.h"
 #include "gstdeinterlace.h"
 #include <string.h>
 
 GType gst_deinterlace_method_weave_tff_get_type (void);
 
 typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodWeaveTFF;
-
 typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodWeaveTFFClass;
 
-
 static void
-deinterlace_scanline_weave (GstDeinterlaceMethod * self,
-    GstDeinterlace * parent, guint8 * out,
-    GstDeinterlaceScanlineData * scanlines, gint width)
+deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
 {
-  oil_memcpy (out, scanlines->m1, parent->row_stride);
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[0]);
 }
 
 static void
-copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace * parent,
-    guint8 * out, GstDeinterlaceScanlineData * scanlines, gint width)
+copy_scanline_packed (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
 {
   /* FIXME: original code used m2 and m0 but this looks really bad */
   if (scanlines->bottom_field) {
-    oil_memcpy (out, scanlines->bb0, parent->row_stride);
+    oil_memcpy (out, scanlines->bb0, self->parent.row_stride[0]);
   } else {
-    oil_memcpy (out, scanlines->bb2, parent->row_stride);
+    oil_memcpy (out, scanlines->bb2, self->parent.row_stride[0]);
   }
 }
 
@@ -84,8 +80,10 @@ gst_deinterlace_method_weave_tff_class_init (GstDeinterlaceMethodWeaveTFFClass *
   dim_class->nick = "weavetff";
   dim_class->latency = 0;
 
-  dism_class->interpolate_scanline = deinterlace_scanline_weave;
-  dism_class->copy_scanline = copy_scanline;
+  dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_yvyu = deinterlace_scanline_weave_packed;
+  dism_class->copy_scanline_yuy2 = copy_scanline_packed;
+  dism_class->copy_scanline_yvyu = copy_scanline_packed;
 }
 
 static void