From 3dc7215492c10a8cc953ff34dee1ff9c0d973980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 21 Apr 2010 17:00:05 +0200 Subject: [PATCH] deinterlace: Refactor deinterlacing as preparation for supporting more color formats --- gst/deinterlace/Makefile.am | 2 +- gst/deinterlace/gstdeinterlace.c | 455 ++++++++++++------ gst/deinterlace/gstdeinterlace.h | 108 +++-- gst/deinterlace/tvtime/greedy.c | 145 +++--- gst/deinterlace/tvtime/greedyh.asm | 39 +- gst/deinterlace/tvtime/greedyh.c | 193 ++++---- gst/deinterlace/tvtime/linear.c | 89 ++-- gst/deinterlace/tvtime/linearblend.c | 121 +++-- gst/deinterlace/tvtime/scalerbob.c | 17 +- gst/deinterlace/tvtime/tomsmocomp.c | 61 ++- .../tvtime/tomsmocomp/TomsMoCompAll.inc | 54 ++- gst/deinterlace/tvtime/vfir.c | 70 +-- gst/deinterlace/tvtime/weave.c | 23 +- gst/deinterlace/tvtime/weavebff.c | 26 +- gst/deinterlace/tvtime/weavetff.c | 26 +- 15 files changed, 839 insertions(+), 590 deletions(-) diff --git a/gst/deinterlace/Makefile.am b/gst/deinterlace/Makefile.am index c5a7ef043d..b5a1bca376 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 0f7af634b6..b3ace11ec1 100644 --- a/gst/deinterlace/gstdeinterlace.c +++ b/gst/deinterlace/gstdeinterlace.c @@ -1,7 +1,7 @@ /* * GStreamer * Copyright (C) 2005 Martin Eikermann - * Copyright (C) 2008-2009 Sebastian Dröge + * Copyright (C) 2008-2010 Sebastian Dröge * * 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 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_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_setup_impl (GstDeinterlaceMethod * self, + GstVideoFormat format, gint width, gint height) +{ + gint i; + GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self); + + 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, - GstDeinterlace * parent, GstBuffer * outbuf) + const GstDeinterlaceField * history, guint history_count, + GstBuffer * outbuf) { - GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self); - - klass->deinterlace_frame (self, parent, 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 void -gst_deinterlace_simple_method_interpolate_scanline (GstDeinterlaceMethod * self, - GstDeinterlace * parent, guint8 * out, - GstDeinterlaceScanlineData * scanlines, gint width) +static gboolean +gst_deinterlace_simple_method_supported (GstDeinterlaceMethodClass * mklass, + GstVideoFormat format, gint width, gint height) { - oil_memcpy (out, scanlines->m1, parent->row_stride); + 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_copy_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->m0, parent->row_stride); + oil_memcpy (out, scanlines->m1, self->parent.row_stride[0]); } static void -gst_deinterlace_simple_method_deinterlace_frame (GstDeinterlaceMethod * self, - GstDeinterlace * parent, GstBuffer * outbuf) +gst_deinterlace_simple_method_copy_scanline_packed (GstDeinterlaceSimpleMethod * + self, guint8 * out, const GstDeinterlaceScanlineData * scanlines) { - GstDeinterlaceSimpleMethodClass *dsm_class = - GST_DEINTERLACE_SIMPLE_METHOD_GET_CLASS (self); + oil_memcpy (out, scanlines->m0, self->parent.row_stride[0]); +} + +static void +gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod * + method, const GstDeinterlaceField * history, guint history_count, + GstBuffer * outbuf) +{ + 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; - field0 = GST_BUFFER_DATA (parent->field_history[cur_field_idx].buf); + g_assert (self->interpolate_scanline_packed != NULL); + g_assert (self->copy_scanline_packed != NULL); + + 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; + dm_class->setup = gst_deinterlace_simple_method_setup; + dm_class->supported = gst_deinterlace_simple_method_supported; - klass->interpolate_scanline = - gst_deinterlace_simple_method_interpolate_scanline; - klass->copy_scanline = gst_deinterlace_simple_method_copy_scanline; + 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 d77128f4fb..7e9602fad7 100644 --- a/gst/deinterlace/gstdeinterlace.h +++ b/gst/deinterlace/gstdeinterlace.h @@ -1,7 +1,7 @@ /* * GStreamer * Copyright (C) 2005 Martin Eikermann - * Copyright (C) 2008-2009 Sebastian Dröge + * Copyright (C) 2008-2010 Sebastian Dröge * * 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 #include + #include #include #include @@ -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; + 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 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; - - /* 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 293d82faa2..3e8a8210e0 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 . * - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 @@ -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 40aa003494..52edfebb12 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 + * Copyright (C) 2008,2010 Sebastian Dröge * * 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; + 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 - int64_t QW256B; - int64_t 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 c72d73d035..49d4da0b48 100644 --- a/gst/deinterlace/tvtime/greedyh.c +++ b/gst/deinterlace/tvtime/greedyh.c @@ -2,7 +2,7 @@ * * GStreamer * Copyright (C) 2004 Billy Biggs - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 -#include "_stdint.h" #include -#include "gst/gst.h" +#include #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; + 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; - 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); + 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 fe57dcb8e4..f354481f8a 100644 --- a/gst/deinterlace/tvtime/linear.c +++ b/gst/deinterlace/tvtime/linear.c @@ -1,6 +1,6 @@ /** * Copyright (C) 2002 Billy Biggs . - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 @@ -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 1a41105cd9..c8f0fc566c 100644 --- a/gst/deinterlace/tvtime/linearblend.c +++ b/gst/deinterlace/tvtime/linearblend.c @@ -4,7 +4,7 @@ * sources. * * Copyright (C) 2002 Billy Biggs . - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 @@ -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 a7bca169f6..bf567ac544 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 + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 @@ -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 cab6fafd56..36412386df 100644 --- a/gst/deinterlace/tvtime/tomsmocomp.c +++ b/gst/deinterlace/tvtime/tomsmocomp.c @@ -1,6 +1,6 @@ /** * Copyright (C) 2004 Billy Biggs - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 -#include "_stdint.h" #include -#include "gst/gst.h" +#include #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 358a9bd88f..23903b3bbb 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; + 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(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); + 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 b3ebaae1a5..e27859d71a 100644 --- a/gst/deinterlace/tvtime/vfir.c +++ b/gst/deinterlace/tvtime/vfir.c @@ -3,7 +3,7 @@ * GStreamer * Copyright (C) 2004 Billy Biggs * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 @@ -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; + if (size > 0) + deinterlace_c (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size); +} - deinterlace_line_c (self, parent, dst, scanlines, width); - } +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 430879a818..16dcd6253e 100644 --- a/gst/deinterlace/tvtime/weave.c +++ b/gst/deinterlace/tvtime/weave.c @@ -1,7 +1,7 @@ /** * Weave frames * Copyright (C) 2002 Billy Biggs . - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 @@ -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 e0b41d57eb..e81a09c132 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 . - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 @@ -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 c567a431c8..1e91026e0d 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 . - * Copyright (C) 2008 Sebastian Dröge + * Copyright (C) 2008,2010 Sebastian Dröge * * 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 @@ -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