summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst/deinterlace/Makefile.am2
-rw-r--r--gst/deinterlace/gstdeinterlace.c455
-rw-r--r--gst/deinterlace/gstdeinterlace.h108
-rw-r--r--gst/deinterlace/tvtime/greedy.c145
-rw-r--r--gst/deinterlace/tvtime/greedyh.asm41
-rw-r--r--gst/deinterlace/tvtime/greedyh.c195
-rw-r--r--gst/deinterlace/tvtime/linear.c89
-rw-r--r--gst/deinterlace/tvtime/linearblend.c121
-rw-r--r--gst/deinterlace/tvtime/scalerbob.c17
-rw-r--r--gst/deinterlace/tvtime/tomsmocomp.c61
-rw-r--r--gst/deinterlace/tvtime/tomsmocomp/TomsMoCompAll.inc56
-rw-r--r--gst/deinterlace/tvtime/vfir.c72
-rw-r--r--gst/deinterlace/tvtime/weave.c23
-rw-r--r--gst/deinterlace/tvtime/weavebff.c26
-rw-r--r--gst/deinterlace/tvtime/weavetff.c26
15 files changed, 843 insertions, 594 deletions
diff --git a/gst/deinterlace/Makefile.am b/gst/deinterlace/Makefile.am
index c5a7ef043..b5a1bca37 100644
--- a/gst/deinterlace/Makefile.am
+++ b/gst/deinterlace/Makefile.am
@@ -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 \
diff --git a/gst/deinterlace/gstdeinterlace.c b/gst/deinterlace/gstdeinterlace.c
index 0f7af634b..b3ace11ec 100644
--- a/gst/deinterlace/gstdeinterlace.c
+++ b/gst/deinterlace/gstdeinterlace.c
@@ -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);
diff --git a/gst/deinterlace/gstdeinterlace.h b/gst/deinterlace/gstdeinterlace.h
index d77128f4f..7e9602fad 100644
--- a/gst/deinterlace/gstdeinterlace.h
+++ b/gst/deinterlace/gstdeinterlace.h
@@ -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__ */
diff --git a/gst/deinterlace/tvtime/greedy.c b/gst/deinterlace/tvtime/greedy.c
index 293d82faa..3e8a8210e 100644
--- a/gst/deinterlace/tvtime/greedy.c
+++ b/gst/deinterlace/tvtime/greedy.c
@@ -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
}
diff --git a/gst/deinterlace/tvtime/greedyh.asm b/gst/deinterlace/tvtime/greedyh.asm
index 40aa00349..52edfebb1 100644
--- a/gst/deinterlace/tvtime/greedyh.asm
+++ b/gst/deinterlace/tvtime/greedyh.asm
@@ -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.
*/
@@ -30,29 +30,28 @@
#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..
diff --git a/gst/deinterlace/tvtime/greedyh.c b/gst/deinterlace/tvtime/greedyh.c
index c72d73d03..49d4da0b4 100644
--- a/gst/deinterlace/tvtime/greedyh.c
+++ b/gst/deinterlace/tvtime/greedyh.c
@@ -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
@@ -32,10 +32,9 @@
#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
}
diff --git a/gst/deinterlace/tvtime/linear.c b/gst/deinterlace/tvtime/linear.c
index fe57dcb8e..f354481f8 100644
--- a/gst/deinterlace/tvtime/linear.c
+++ b/gst/deinterlace/tvtime/linear.c
@@ -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>
@@ -42,33 +41,36 @@
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
}
diff --git a/gst/deinterlace/tvtime/linearblend.c b/gst/deinterlace/tvtime/linearblend.c
index 1a41105cd..c8f0fc566 100644
--- a/gst/deinterlace/tvtime/linearblend.c
+++ b/gst/deinterlace/tvtime/linearblend.c
@@ -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>
@@ -46,57 +45,55 @@
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
}
diff --git a/gst/deinterlace/tvtime/scalerbob.c b/gst/deinterlace/tvtime/scalerbob.c
index a7bca169f..bf567ac54 100644
--- a/gst/deinterlace/tvtime/scalerbob.c
+++ b/gst/deinterlace/tvtime/scalerbob.c
@@ -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>
@@ -37,16 +36,13 @@
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
diff --git a/gst/deinterlace/tvtime/tomsmocomp.c b/gst/deinterlace/tvtime/tomsmocomp.c
index cab6fafd5..36412386d 100644
--- a/gst/deinterlace/tvtime/tomsmocomp.c
+++ b/gst/deinterlace/tvtime/tomsmocomp.c
@@ -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
@@ -28,10 +28,9 @@
#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
}
diff --git a/gst/deinterlace/tvtime/tomsmocomp/TomsMoCompAll.inc b/gst/deinterlace/tvtime/tomsmocomp/TomsMoCompAll.inc
index 358a9bd88..23903b3bb 100644
--- a/gst/deinterlace/tvtime/tomsmocomp/TomsMoCompAll.inc
+++ b/gst/deinterlace/tvtime/tomsmocomp/TomsMoCompAll.inc
@@ -61,36 +61,44 @@
#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
diff --git a/gst/deinterlace/tvtime/vfir.c b/gst/deinterlace/tvtime/vfir.c
index b3ebaae1a..e27859d71 100644
--- a/gst/deinterlace/tvtime/vfir.c
+++ b/gst/deinterlace/tvtime/vfir.c
@@ -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
}
diff --git a/gst/deinterlace/tvtime/weave.c b/gst/deinterlace/tvtime/weave.c
index 430879a81..16dcd6253 100644
--- a/gst/deinterlace/tvtime/weave.c
+++ b/gst/deinterlace/tvtime/weave.c
@@ -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>
@@ -43,23 +42,20 @@
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
diff --git a/gst/deinterlace/tvtime/weavebff.c b/gst/deinterlace/tvtime/weavebff.c
index e0b41d57e..e81a09c13 100644
--- a/gst/deinterlace/tvtime/weavebff.c
+++ b/gst/deinterlace/tvtime/weavebff.c
@@ -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>
@@ -43,27 +42,24 @@
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
diff --git a/gst/deinterlace/tvtime/weavetff.c b/gst/deinterlace/tvtime/weavetff.c
index c567a431c..1e91026e0 100644
--- a/gst/deinterlace/tvtime/weavetff.c
+++ b/gst/deinterlace/tvtime/weavetff.c
@@ -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>
@@ -44,27 +43,24 @@
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