diff options
Diffstat (limited to 'gst/deinterlace2/tvtime')
-rw-r--r-- | gst/deinterlace2/tvtime/greedy.c | 212 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/greedyh.asm | 11 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/greedyh.c | 215 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/greedyh.h | 45 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/plugins.h | 14 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/tomsmocomp.c | 162 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/tomsmocomp.h | 56 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/tomsmocomp/TomsMoCompAll.inc | 35 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/vfir.c | 95 |
9 files changed, 491 insertions, 354 deletions
diff --git a/gst/deinterlace2/tvtime/greedy.c b/gst/deinterlace2/tvtime/greedy.c index 904a24b3..434c332f 100644 --- a/gst/deinterlace2/tvtime/greedy.c +++ b/gst/deinterlace2/tvtime/greedy.c @@ -4,6 +4,8 @@ * 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> + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -35,6 +37,30 @@ #include "gstdeinterlace2.h" #include <string.h> +#define GST_TYPE_DEINTERLACE_METHOD_GREEDY_L (gst_deinterlace_method_greedy_l_get_type ()) +#define GST_IS_DEINTERLACE_METHOD_GREEDY_L(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L)) +#define GST_IS_DEINTERLACE_METHOD_GREEDY_L_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L)) +#define GST_DEINTERLACE_METHOD_GREEDY_L_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L, GstDeinterlaceMethodGreedyLClass)) +#define GST_DEINTERLACE_METHOD_GREEDY_L(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L, GstDeinterlaceMethodGreedyL)) +#define GST_DEINTERLACE_METHOD_GREEDY_L_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_L, GstDeinterlaceMethodGreedyLClass)) +#define GST_DEINTERLACE_METHOD_GREEDY_L_CAST(obj) ((GstDeinterlaceMethodGreedyL*)(obj)) + +GType gst_deinterlace_method_greedy_l_get_type (void); + +typedef struct +{ + GstDeinterlaceMethod parent; + + guint max_comb; +} GstDeinterlaceMethodGreedyL; + +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); +} GstDeinterlaceMethodGreedyLClass; + // This is a simple lightweight DeInterlace method that uses little CPU time // but gives very good results for low or intermedite motion. // It defers frames by one field, but that does not seem to produce noticeable @@ -47,13 +73,13 @@ // I'd intended this to be part of a larger more elaborate method added to // Blended Clip but this give too good results for the CPU to ignore here. -static const int GreedyMaxComb = 15; - static inline void -deinterlace_greedy_packed422_scanline_c (uint8_t * m0, uint8_t * t1, +deinterlace_greedy_packed422_scanline_c (GstDeinterlaceMethodGreedyL * self, + uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, uint8_t * output, int width) { int avg, l2_diff, lp2_diff, max, min, best; + guint max_comb = self->max_comb; // L2 == m0 // L1 == t1 @@ -74,13 +100,13 @@ deinterlace_greedy_packed422_scanline_c (uint8_t * m0, uint8_t * t1, max = MAX (*t1, *b1); min = MIN (*t1, *b1); - if (max < 256 - GreedyMaxComb) - max += GreedyMaxComb; + if (max < 256 - max_comb) + max += max_comb; else max = 255; - if (min > GreedyMaxComb) - min -= GreedyMaxComb; + if (min > max_comb) + min -= max_comb; else min = 0; @@ -98,22 +124,22 @@ deinterlace_greedy_packed422_scanline_c (uint8_t * m0, uint8_t * t1, #ifdef HAVE_CPU_I386 #include "mmx.h" static void -deinterlace_greedy_packed422_scanline_mmx (uint8_t * m0, uint8_t * t1, +deinterlace_greedy_packed422_scanline_mmx (GstDeinterlaceMethodGreedyL * self, + uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, uint8_t * output, int width) { mmx_t MaxComb; - mmx_t ShiftMask; // How badly do we let it weave? 0-255 - MaxComb.ub[0] = GreedyMaxComb; - MaxComb.ub[1] = GreedyMaxComb; - MaxComb.ub[2] = GreedyMaxComb; - MaxComb.ub[3] = GreedyMaxComb; - MaxComb.ub[4] = GreedyMaxComb; - MaxComb.ub[5] = GreedyMaxComb; - MaxComb.ub[6] = GreedyMaxComb; - MaxComb.ub[7] = GreedyMaxComb; + MaxComb.ub[0] = self->max_comb; + MaxComb.ub[1] = self->max_comb; + MaxComb.ub[2] = self->max_comb; + MaxComb.ub[3] = self->max_comb; + MaxComb.ub[4] = self->max_comb; + MaxComb.ub[5] = self->max_comb; + MaxComb.ub[6] = self->max_comb; + MaxComb.ub[7] = self->max_comb; ShiftMask.ub[0] = 0x7f; ShiftMask.ub[1] = 0x7f; @@ -207,26 +233,28 @@ deinterlace_greedy_packed422_scanline_mmx (uint8_t * m0, uint8_t * t1, } emms (); if (width > 0) - deinterlace_greedy_packed422_scanline_c (m0, t1, b1, m2, output, width); + deinterlace_greedy_packed422_scanline_c (self, m0, t1, b1, m2, output, + width); } #include "sse.h" static void -deinterlace_greedy_packed422_scanline_mmxext (uint8_t * m0, uint8_t * t1, - uint8_t * b1, uint8_t * m2, uint8_t * output, int width) +deinterlace_greedy_packed422_scanline_mmxext (GstDeinterlaceMethodGreedyL * + self, uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, + uint8_t * output, int width) { mmx_t MaxComb; // How badly do we let it weave? 0-255 - MaxComb.ub[0] = GreedyMaxComb; - MaxComb.ub[1] = GreedyMaxComb; - MaxComb.ub[2] = GreedyMaxComb; - MaxComb.ub[3] = GreedyMaxComb; - MaxComb.ub[4] = GreedyMaxComb; - MaxComb.ub[5] = GreedyMaxComb; - MaxComb.ub[6] = GreedyMaxComb; - MaxComb.ub[7] = GreedyMaxComb; + MaxComb.ub[0] = self->max_comb; + MaxComb.ub[1] = self->max_comb; + MaxComb.ub[2] = self->max_comb; + MaxComb.ub[3] = self->max_comb; + MaxComb.ub[4] = self->max_comb; + MaxComb.ub[5] = self->max_comb; + MaxComb.ub[6] = self->max_comb; + MaxComb.ub[7] = self->max_comb; // L2 == m0 // L1 == t1 @@ -299,17 +327,20 @@ deinterlace_greedy_packed422_scanline_mmxext (uint8_t * m0, uint8_t * t1, emms (); if (width > 0) - deinterlace_greedy_packed422_scanline_c (m0, t1, b1, m2, output, width); + deinterlace_greedy_packed422_scanline_c (self, m0, t1, b1, m2, output, + width); } #endif static void -deinterlace_frame_di_greedy (GstDeinterlace2 * object) +deinterlace_frame_di_greedy (GstDeinterlaceMethod * d_method, + GstDeinterlace2 * object) { - void (*func) (uint8_t * L2, uint8_t * L1, uint8_t * L3, uint8_t * L2P, - uint8_t * Dest, int size); - + GstDeinterlaceMethodGreedyL *self = + GST_DEINTERLACE_METHOD_GREEDY_L (d_method); + GstDeinterlaceMethodGreedyLClass *klass = + GST_DEINTERLACE_METHOD_GREEDY_L_GET_CLASS (self); int InfoIsOdd = 0; int Line; unsigned int Pitch = object->field_stride; @@ -320,18 +351,6 @@ deinterlace_frame_di_greedy (GstDeinterlace2 * object) unsigned char *L2P; // ptr to prev Line2 unsigned char *Dest = GST_BUFFER_DATA (object->out_buf); -#ifdef HAVE_CPU_I386 - if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMXEXT) { - func = deinterlace_greedy_packed422_scanline_mmxext; - } else if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) { - func = deinterlace_greedy_packed422_scanline_mmx; - } else { - func = deinterlace_greedy_packed422_scanline_c; - } -#else - func = deinterlace_greedy_packed422_scanline_c; -#endif - // 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.) @@ -368,7 +387,7 @@ deinterlace_frame_di_greedy (GstDeinterlace2 * object) } for (Line = 0; Line < (object->field_height - 1); ++Line) { - func (L2, L1, L3, L2P, Dest, object->line_length); + klass->scanline (self, L2, L1, L3, L2P, Dest, object->line_length); Dest += object->output_stride; memcpy (Dest, L3, object->line_length); Dest += object->output_stride; @@ -384,31 +403,84 @@ deinterlace_frame_di_greedy (GstDeinterlace2 * object) } } -static deinterlace_method_t greedyl_method = { - 0, //DEINTERLACE_PLUGIN_API_VERSION, - "Motion Adaptive: Simple Detection", - "AdaptiveSimple", - 4, - 0, - 0, - 0, - 0, - 1, - deinterlace_frame_di_greedy, - {"Uses heuristics to detect motion in the input", - "frames and reconstruct image detail where", - "possible. Use this for high quality output", - "even on monitors set to an arbitrary refresh", - "rate.", - "", - "Simple detection uses linear interpolation", - "where motion is detected, using a two-field", - "buffer. This is the Greedy: Low Motion", - "deinterlacer from DScaler."} + +G_DEFINE_TYPE (GstDeinterlaceMethodGreedyL, gst_deinterlace_method_greedy_l, + GST_TYPE_DEINTERLACE_METHOD); + +enum +{ + ARG_0, + ARG_MAX_COMB }; -deinterlace_method_t * -dscaler_greedyl_get_method (void) +static void +gst_deinterlace_method_greedy_l_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (object); + + switch (prop_id) { + case ARG_MAX_COMB: + self->max_comb = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_deinterlace_method_greedy_l_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (object); + + switch (prop_id) { + case ARG_MAX_COMB: + g_value_set_uint (value, self->max_comb); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_deinterlace_method_greedy_l_class_init (GstDeinterlaceMethodGreedyLClass * + klass) +{ + GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass; + GObjectClass *gobject_class = (GObjectClass *) klass; + guint cpu_flags = oil_cpu_get_flags (); + + 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_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; + +#ifdef HAVE_CPU_I386 + if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) { + klass->scanline = deinterlace_greedy_packed422_scanline_mmxext; + } else if (cpu_flags & OIL_IMPL_FLAG_MMX) { + klass->scanline = deinterlace_greedy_packed422_scanline_mmx; + } else { + klass->scanline = deinterlace_greedy_packed422_scanline_c; + } +#else + klass->scanline = deinterlace_greedy_packed422_scanline_c; +#endif +} + +static void +gst_deinterlace_method_greedy_l_init (GstDeinterlaceMethodGreedyL * self) { - return &greedyl_method; + self->max_comb = 15; } diff --git a/gst/deinterlace2/tvtime/greedyh.asm b/gst/deinterlace2/tvtime/greedyh.asm index 5deaedad..3cc88945 100644 --- a/gst/deinterlace2/tvtime/greedyh.asm +++ b/gst/deinterlace2/tvtime/greedyh.asm @@ -2,6 +2,7 @@ * * GStreamer * Copyright (c) 2001 Tom Barry. All rights reserved. + * Copyright (C) 2008 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 @@ -29,7 +30,7 @@ #include "x86-64_macros.inc" void -FUNCT_NAME (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, +FUNCT_NAME (GstDeinterlaceMethodGreedyH *self, uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, uint8_t * Dest, int size) { @@ -49,14 +50,14 @@ FUNCT_NAME (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, int64_t LastAvg = 0; //interp value from left qword // Set up our two parms that are actually evaluated for each pixel - i = GreedyMaxComb; + i = self->max_comb; MaxComb = i << 56 | i << 48 | i << 40 | i << 32 | i << 24 | i << 16 | i << 8 | i; - i = GreedyMotionThreshold; // scale to range of 0-257 + i = self->motion_threshold; // scale to range of 0-257 MotionThreshold = i << 48 | i << 32 | i << 16 | i | UVMask; - i = GreedyMotionSense; // scale to range of 0-257 + i = self->motion_sense; // scale to range of 0-257 MotionSense = i << 48 | i << 32 | i << 16 | i; i = 0xffffffff - 256; @@ -243,6 +244,6 @@ FUNCT_NAME (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, if (size % 8 != 0) { int offset = GST_ROUND_DOWN_8 (size); - greedyDScaler_C (L1 + offset, L2 + offset, L3 + offset, L2P + offset, Dest + offset, size % 8); + greedyDScaler_C (self, L1 + offset, L2 + offset, L3 + offset, L2P + offset, Dest + offset, size % 8); } } diff --git a/gst/deinterlace2/tvtime/greedyh.c b/gst/deinterlace2/tvtime/greedyh.c index 72f43781..530d6289 100644 --- a/gst/deinterlace2/tvtime/greedyh.c +++ b/gst/deinterlace2/tvtime/greedyh.c @@ -2,6 +2,7 @@ * * GStreamer * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net> + * Copyright (C) 2008 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,7 +29,6 @@ # include "config.h" #endif -#include "greedyh.h" #include "greedyhmacros.h" #include <stdlib.h> @@ -39,13 +39,33 @@ #include "plugins.h" #include "gstdeinterlace2.h" -static const unsigned int GreedyMaxComb = 5; -static const unsigned int GreedyMotionThreshold = 25; -static const unsigned int GreedyMotionSense = 30; +#define GST_TYPE_DEINTERLACE_METHOD_GREEDY_H (gst_deinterlace_method_greedy_h_get_type ()) +#define GST_IS_DEINTERLACE_METHOD_GREEDY_H(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H)) +#define GST_IS_DEINTERLACE_METHOD_GREEDY_H_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H)) +#define GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyHClass)) +#define GST_DEINTERLACE_METHOD_GREEDY_H(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyH)) +#define GST_DEINTERLACE_METHOD_GREEDY_H_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyHClass)) +#define GST_DEINTERLACE_METHOD_GREEDY_H_CAST(obj) ((GstDeinterlaceMethodGreedyH*)(obj)) + +GType gst_deinterlace_method_greedy_h_get_type (void); + +typedef struct +{ + GstDeinterlaceMethod parent; + + guint max_comb, motion_threshold, motion_sense; +} GstDeinterlaceMethodGreedyH; + +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); +} GstDeinterlaceMethodGreedyHClass; void -greedyDScaler_C (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, - uint8_t * Dest, int size) +greedyDScaler_C (GstDeinterlaceMethodGreedyH * self, uint8_t * L1, uint8_t * L2, + uint8_t * L3, uint8_t * L2P, uint8_t * Dest, int size) { int Pos; uint8_t l1_l, l1_1_l, l3_l, l3_1_l; @@ -60,6 +80,9 @@ greedyDScaler_C (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, 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; + 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) { l1_l = L1[0]; @@ -130,26 +153,26 @@ greedyDScaler_C (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, max_l = MAX (l1_l, l3_l); min_l = MIN (l1_l, l3_l); - if (max_l < 256 - GreedyMaxComb) - max_l += GreedyMaxComb; + if (max_l < 256 - max_comb) + max_l += max_comb; else max_l = 255; - if (min_l > GreedyMaxComb) - min_l -= GreedyMaxComb; + if (min_l > max_comb) + min_l -= max_comb; else min_l = 0; max_c = MAX (l1_c, l3_c); min_c = MIN (l1_c, l3_c); - if (max_c < 256 - GreedyMaxComb) - max_c += GreedyMaxComb; + if (max_c < 256 - max_comb) + max_c += max_comb; else max_c = 255; - if (min_c > GreedyMaxComb) - min_c -= GreedyMaxComb; + if (min_c > max_comb) + min_c -= max_comb; else min_c = 0; @@ -159,12 +182,12 @@ greedyDScaler_C (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, /* Do motion compensation for luma, i.e. how much * the weave pixel differs */ mov_l = ABS (l2_l - lp2_l); - if (mov_l > GreedyMotionThreshold) - mov_l -= GreedyMotionThreshold; + if (mov_l > motion_threshold) + mov_l -= motion_threshold; else mov_l = 0; - mov_l = mov_l * GreedyMotionSense; + mov_l = mov_l * motion_sense; if (mov_l > 256) mov_l = 256; @@ -211,11 +234,13 @@ greedyDScaler_C (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, #endif static void -deinterlace_frame_di_greedyh (GstDeinterlace2 * object) +deinterlace_frame_di_greedyh (GstDeinterlaceMethod * d_method, + GstDeinterlace2 * object) { - void (*func) (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P, - uint8_t * Dest, int size); - + GstDeinterlaceMethodGreedyH *self = + GST_DEINTERLACE_METHOD_GREEDY_H (d_method); + GstDeinterlaceMethodGreedyHClass *klass = + GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self); int InfoIsOdd = 0; int Line; unsigned int Pitch = object->field_stride; @@ -227,20 +252,6 @@ deinterlace_frame_di_greedyh (GstDeinterlace2 * object) unsigned char *L2P; // ptr to prev Line2 unsigned char *Dest = GST_BUFFER_DATA (object->out_buf); -#ifdef HAVE_CPU_I386 - if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMXEXT) { - func = greedyDScaler_MMXEXT; - } else if (object->cpu_feature_flags & OIL_IMPL_FLAG_3DNOW) { - func = greedyDScaler_3DNOW; - } else if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) { - func = greedyDScaler_MMX; - } else { - func = greedyDScaler_C; - } -#else - func = greedyDScaler_C; -#endif - // 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.) @@ -277,7 +288,7 @@ deinterlace_frame_di_greedyh (GstDeinterlace2 * object) } for (Line = 0; Line < (object->field_height - 1); ++Line) { - func (L1, L2, L3, L2P, Dest, object->line_length); + klass->scanline (self, L1, L2, L3, L2P, Dest, object->line_length); Dest += object->output_stride; memcpy (Dest, L3, object->line_length); Dest += object->output_stride; @@ -293,31 +304,115 @@ deinterlace_frame_di_greedyh (GstDeinterlace2 * object) } } -static deinterlace_method_t greedyh_method = { - 0, //DEINTERLACE_PLUGIN_API_VERSION, - "Motion Adaptive: Advanced Detection", - "AdaptiveAdvanced", - 4, - 0, - 0, - 0, - 0, - 0, - deinterlace_frame_di_greedyh, - {"Uses heuristics to detect motion in the input", - "frames and reconstruct image detail where", - "possible. Use this for high quality output", - "even on monitors set to an arbitrary refresh", - "rate.", - "", - "Advanced detection uses linear interpolation", - "where motion is detected, using a four-field", - "buffer. This is the Greedy: High Motion", - "deinterlacer from DScaler."} +G_DEFINE_TYPE (GstDeinterlaceMethodGreedyH, gst_deinterlace_method_greedy_h, + GST_TYPE_DEINTERLACE_METHOD); + +enum +{ + ARG_0, + ARG_MAX_COMB, + ARG_MOTION_THRESHOLD, + ARG_MOTION_SENSE }; -deinterlace_method_t * -dscaler_greedyh_get_method (void) +static void +gst_deinterlace_method_greedy_h_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (object); + + switch (prop_id) { + case ARG_MAX_COMB: + self->max_comb = g_value_get_uint (value); + break; + case ARG_MOTION_THRESHOLD: + self->motion_threshold = g_value_get_uint (value); + break; + case ARG_MOTION_SENSE: + self->motion_sense = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_deinterlace_method_greedy_h_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (object); + + switch (prop_id) { + case ARG_MAX_COMB: + g_value_set_uint (value, self->max_comb); + break; + case ARG_MOTION_THRESHOLD: + g_value_set_uint (value, self->motion_threshold); + break; + case ARG_MOTION_SENSE: + g_value_set_uint (value, self->motion_sense); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_deinterlace_method_greedy_h_class_init (GstDeinterlaceMethodGreedyHClass * + klass) +{ + GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass; + GObjectClass *gobject_class = (GObjectClass *) klass; + guint cpu_flags = oil_cpu_get_flags (); + + 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_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_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_param_spec_uint ("motion-sense", + "Motion Sense", + "Motion Sense", + 0, 255, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) + ); + + 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; + +#ifdef HAVE_CPU_I386 + if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) { + klass->scanline = greedyDScaler_MMXEXT; + } else if (cpu_flags & OIL_IMPL_FLAG_3DNOW) { + klass->scanline = greedyDScaler_3DNOW; + } else if (cpu_flags & OIL_IMPL_FLAG_MMX) { + klass->scanline = greedyDScaler_MMX; + } else { + klass->scanline = greedyDScaler_C; + } +#else + klass->scanline = greedyDScaler_C; +#endif +} + +static void +gst_deinterlace_method_greedy_h_init (GstDeinterlaceMethodGreedyH * self) { - return &greedyh_method; + self->max_comb = 5; + self->motion_threshold = 25; + self->motion_sense = 30; } diff --git a/gst/deinterlace2/tvtime/greedyh.h b/gst/deinterlace2/tvtime/greedyh.h deleted file mode 100644 index 1156836a..00000000 --- a/gst/deinterlace2/tvtime/greedyh.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * GStreamer - * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Relicensed for GStreamer from GPL to LGPL with permit from Billy Biggs. - * See: http://bugzilla.gnome.org/show_bug.cgi?id=163578 - */ - -#ifndef GREEDYH_H_INCLUDED -#define GREEDYH_H_INCLUDED - -#include "gstdeinterlace2.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void greedyh_init( void ); -void greedyh_filter_mmx( GstDeinterlace2 *object ); -void greedyh_filter_3dnow( GstDeinterlace2 *object ); -void greedyh_filter_sse( GstDeinterlace2 *object ); - -#ifdef __cplusplus -}; -#endif - -#endif /* GREEDYH_H_INCLUDED */ diff --git a/gst/deinterlace2/tvtime/plugins.h b/gst/deinterlace2/tvtime/plugins.h index 0eb90c0b..19d9aed9 100644 --- a/gst/deinterlace2/tvtime/plugins.h +++ b/gst/deinterlace2/tvtime/plugins.h @@ -2,6 +2,7 @@ * * GStreamer * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net> + * Copyright (C) 2008 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 @@ -27,10 +28,15 @@ #ifndef TVTIME_PLUGINS_H_INCLUDED #define TVTIME_PLUGINS_H_INCLUDED -deinterlace_method_t* dscaler_tomsmocomp_get_method( void ); -deinterlace_method_t* dscaler_greedyh_get_method( void ); -deinterlace_method_t* dscaler_greedyl_get_method( void ); -deinterlace_method_t* dscaler_vfir_get_method( void ); +#define GST_TYPE_DEINTERLACE_TOMSMOCOMP (gst_deinterlace_method_tomsmocomp_get_type ()) +#define GST_TYPE_DEINTERLACE_GREEDY_H (gst_deinterlace_method_greedy_h_get_type ()) +#define GST_TYPE_DEINTERLACE_GREEDY_L (gst_deinterlace_method_greedy_l_get_type ()) +#define GST_TYPE_DEINTERLACE_VFIR (gst_deinterlace_method_vfir_get_type ()) + +GType gst_deinterlace_method_tomsmocomp_get_type (void); +GType gst_deinterlace_method_greedy_h_get_type (void); +GType gst_deinterlace_method_greedy_l_get_type (void); +GType gst_deinterlace_method_vfir_get_type (void); //void linear_plugin_init( void ); //void scalerbob_plugin_init( void ); diff --git a/gst/deinterlace2/tvtime/tomsmocomp.c b/gst/deinterlace2/tvtime/tomsmocomp.c index 65234c2c..7a0ba6b3 100644 --- a/gst/deinterlace2/tvtime/tomsmocomp.c +++ b/gst/deinterlace2/tvtime/tomsmocomp.c @@ -1,5 +1,6 @@ /** * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net> + * Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,22 +32,28 @@ #include "tomsmocomp/tomsmocompmacros.h" #include "x86-64_macros.inc" -#define SearchEffortDefault 5 -#define UseStrangeBobDefault 0 - -static long SearchEffort; -static int UseStrangeBob; -static int IsOdd; -static const unsigned char *pWeaveSrc; -static const unsigned char *pWeaveSrcP; -static unsigned char *pWeaveDest; -static const unsigned char *pCopySrc; -static const unsigned char *pCopySrcP; -static unsigned char *pCopyDest; -static int src_pitch; -static int dst_pitch; -static int rowsize; -static int FldHeight; +#define GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP (gst_deinterlace_method_tomsmocomp_get_type ()) +#define GST_IS_DEINTERLACE_METHOD_TOMSMOCOMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP)) +#define GST_IS_DEINTERLACE_METHOD_TOMSMOCOMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP)) +#define GST_DEINTERLACE_METHOD_TOMSMOCOMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoCompClass)) +#define GST_DEINTERLACE_METHOD_TOMSMOCOMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoComp)) +#define GST_DEINTERLACE_METHOD_TOMSMOCOMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoCompClass)) +#define GST_DEINTERLACE_METHOD_TOMSMOCOMP_CAST(obj) ((GstDeinterlaceMethodTomsMoComp*)(obj)) + +GType gst_deinterlace_method_tomsmocomp_get_type (void); + +typedef struct +{ + GstDeinterlaceMethod parent; + + guint search_effort; + gboolean strange_bob; +} GstDeinterlaceMethodTomsMoComp; + +typedef struct +{ + GstDeinterlaceMethodClass parent_class; +} GstDeinterlaceMethodTomsMoCompClass; static int Fieldcopy (void *dest, const void *src, size_t count, @@ -90,71 +97,96 @@ Fieldcopy (void *dest, const void *src, size_t count, #undef SSE_TYPE #undef FUNCT_NAME -static void -tomsmocomp_init (void) -{ - SearchEffort = SearchEffortDefault; - UseStrangeBob = UseStrangeBobDefault; -} +G_DEFINE_TYPE (GstDeinterlaceMethodTomsMoComp, + gst_deinterlace_method_tomsmocomp, GST_TYPE_DEINTERLACE_METHOD); -static void -tomsmocomp_filter_mmx (GstDeinterlace2 * object) +enum { - tomsmocompDScaler_MMX (object); -} + ARG_0, + ARG_SEARCH_EFFORT, + ARG_STRANGE_BOB +}; static void -tomsmocomp_filter_3dnow (GstDeinterlace2 * object) +gst_deinterlace_method_tomsmocomp_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { - tomsmocompDScaler_3DNOW (object); + GstDeinterlaceMethodTomsMoComp *self = + GST_DEINTERLACE_METHOD_TOMSMOCOMP (object); + + switch (prop_id) { + case ARG_SEARCH_EFFORT: + self->search_effort = g_value_get_uint (value); + break; + case ARG_STRANGE_BOB: + self->strange_bob = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } } static void -tomsmocomp_filter_sse (GstDeinterlace2 * object) +gst_deinterlace_method_tomsmocomp_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) { - tomsmocompDScaler_SSE (object); + GstDeinterlaceMethodTomsMoComp *self = + GST_DEINTERLACE_METHOD_TOMSMOCOMP (object); + + switch (prop_id) { + case ARG_SEARCH_EFFORT: + g_value_set_uint (value, self->search_effort); + break; + case ARG_STRANGE_BOB: + g_value_set_boolean (value, self->strange_bob); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } } static void -deinterlace_frame_di_tomsmocomp (GstDeinterlace2 * object) + gst_deinterlace_method_tomsmocomp_class_init + (GstDeinterlaceMethodTomsMoCompClass * klass) { - if (object->cpu_feature_flags & OIL_IMPL_FLAG_SSE) { - tomsmocomp_filter_sse (object); - } else if (object->cpu_feature_flags & OIL_IMPL_FLAG_3DNOW) { - tomsmocomp_filter_3dnow (object); - } else if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) { - tomsmocomp_filter_mmx (object); + GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass; + GObjectClass *gobject_class = (GObjectClass *) klass; + guint cpu_flags = oil_cpu_get_flags (); + + 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_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_param_spec_boolean ("strange-bob", + "Strange Bob", + "Use strange bob", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) + ); + + dim_class->fields_required = 4; + dim_class->name = "Motion Adaptive: Motion Search"; + dim_class->nick = "tomsmocomp"; + dim_class->latency = 1; + + if (cpu_flags & OIL_IMPL_FLAG_SSE) { + dim_class->deinterlace_frame = tomsmocompDScaler_SSE; + } else if (cpu_flags & OIL_IMPL_FLAG_3DNOW) { + dim_class->deinterlace_frame = tomsmocompDScaler_3DNOW; + } else if (cpu_flags & OIL_IMPL_FLAG_MMX) { + dim_class->deinterlace_frame = tomsmocompDScaler_MMX; } else { - g_assert_not_reached (); + dim_class->available = FALSE; } } -static deinterlace_method_t tomsmocompmethod = { - 0, //DEINTERLACE_PLUGIN_API_VERSION, - "Motion Adaptive: Motion Search", - "AdaptiveSearch", - 4, - OIL_IMPL_FLAG_MMX, - 0, - 0, - 0, - 0, - deinterlace_frame_di_tomsmocomp, - {"Uses heuristics to detect motion in the input", - "frames and reconstruct image detail where", - "possible. Use this for high quality output", - "even on monitors set to an arbitrary refresh", - "rate.", - "", - "Motion search mode finds and follows motion", - "vectors for accurate interpolation. This is", - "the TomsMoComp deinterlacer from DScaler.", - ""} -}; - -deinterlace_method_t * -dscaler_tomsmocomp_get_method (void) +static void +gst_deinterlace_method_tomsmocomp_init (GstDeinterlaceMethodTomsMoComp * self) { - tomsmocomp_init (); - return &tomsmocompmethod; + self->search_effort = 5; + self->strange_bob = FALSE; } diff --git a/gst/deinterlace2/tvtime/tomsmocomp.h b/gst/deinterlace2/tvtime/tomsmocomp.h deleted file mode 100644 index ca40ac44..00000000 --- a/gst/deinterlace2/tvtime/tomsmocomp.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef TOMSMOCOMP_H_INCLUDED -#define TOMSMOCOMP_H_INCLUDED - -#include "gstdeinterlace2.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int Search_Effort_0(); -int Search_Effort_1(); -int Search_Effort_3(); -int Search_Effort_5(); -int Search_Effort_9(); -int Search_Effort_11(); -int Search_Effort_13(); -int Search_Effort_15(); -int Search_Effort_19(); -int Search_Effort_21(); -int Search_Effort_Max(); - -int Search_Effort_0_SB(); -int Search_Effort_1_SB(); -int Search_Effort_3_SB(); -int Search_Effort_5_SB(); -int Search_Effort_9_SB(); -int Search_Effort_11_SB(); -int Search_Effort_13_SB(); -int Search_Effort_15_SB(); -int Search_Effort_19_SB(); -int Search_Effort_21_SB(); -int Search_Effort_Max_SB(); - -#ifdef __cplusplus -}; -#endif - -#endif /* TOMSMOCOMP_H_INCLUDED */ diff --git a/gst/deinterlace2/tvtime/tomsmocomp/TomsMoCompAll.inc b/gst/deinterlace2/tvtime/tomsmocomp/TomsMoCompAll.inc index 2318f6a3..743b6e8d 100644 --- a/gst/deinterlace2/tvtime/tomsmocomp/TomsMoCompAll.inc +++ b/gst/deinterlace2/tvtime/tomsmocomp/TomsMoCompAll.inc @@ -33,11 +33,11 @@ #endif #if defined(IS_SSE) -#define SEFUNC(x) Search_Effort_SSE_##x() +#define SEFUNC(x) Search_Effort_SSE_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight) #elif defined(IS_3DNOW) -#define SEFUNC(x) Search_Effort_3DNOW_##x() +#define SEFUNC(x) Search_Effort_3DNOW_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight) #else -#define SEFUNC(x) Search_Effort_MMX_##x() +#define SEFUNC(x) Search_Effort_MMX_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight) #endif #include "TomsMoCompAll2.inc" @@ -48,9 +48,32 @@ #undef USE_STRANGE_BOB +#undef SEFUNC +#if defined(IS_SSE) +#define SEFUNC(x) Search_Effort_SSE_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight) +#elif defined(IS_3DNOW) +#define SEFUNC(x) Search_Effort_3DNOW_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight) +#else +#define SEFUNC(x) Search_Effort_MMX_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight) +#endif -void FUNCT_NAME(GstDeinterlace2* object) +void FUNCT_NAME(GstDeinterlaceMethod *d_method, GstDeinterlace2* object) { + 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; + /* double stride do address just every odd/even scanline */ src_pitch = object->field_stride; dst_pitch = object->output_stride; @@ -80,10 +103,6 @@ void FUNCT_NAME(GstDeinterlace2* object) } -#ifdef IS_SSE2 - // SSE2 support temporarily deleted -#endif - // copy 1st and last weave lines Fieldcopy(pWeaveDest, pCopySrc, rowsize, 1, dst_pitch*2, src_pitch); diff --git a/gst/deinterlace2/tvtime/vfir.c b/gst/deinterlace2/tvtime/vfir.c index 3a56f850..fcfbaa6b 100644 --- a/gst/deinterlace2/tvtime/vfir.c +++ b/gst/deinterlace2/tvtime/vfir.c @@ -3,6 +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> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -36,6 +37,26 @@ #include "gstdeinterlace2.h" #include <string.h> +#define GST_TYPE_DEINTERLACE_METHOD_VFIR (gst_deinterlace_method_vfir_get_type ()) +#define GST_IS_DEINTERLACE_METHOD_VFIR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_VFIR)) +#define GST_IS_DEINTERLACE_METHOD_VFIR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_VFIR)) +#define GST_DEINTERLACE_METHOD_VFIR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_VFIR, GstDeinterlaceMethodVFIRClass)) +#define GST_DEINTERLACE_METHOD_VFIR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_VFIR, GstDeinterlaceMethodVFIR)) +#define GST_DEINTERLACE_METHOD_VFIR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_VFIR, GstDeinterlaceMethodVFIRClass)) +#define GST_DEINTERLACE_METHOD_VFIR_CAST(obj) ((GstDeinterlaceMethodVFIR*)(obj)) + +GType gst_deinterlace_method_vfir_get_type (void); + +typedef GstDeinterlaceMethod GstDeinterlaceMethodVFIR; + +typedef struct +{ + GstDeinterlaceMethodClass parent_class; + void (*scanline) (uint8_t * dst, uint8_t * lum_m4, + uint8_t * lum_m3, uint8_t * lum_m2, + uint8_t * lum_m1, uint8_t * lum, int size); +} GstDeinterlaceMethodVFIRClass; + /* * The MPEG2 spec uses a slightly harsher filter, they specify * [-1 8 2 8 -1]. ffmpeg uses a similar filter but with more of @@ -122,25 +143,15 @@ deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4, #endif static void -deinterlace_frame_vfir (GstDeinterlace2 * object) +deinterlace_frame_vfir (GstDeinterlaceMethod * d_method, + GstDeinterlace2 * object) { - void (*func) (uint8_t * dst, uint8_t * lum_m4, - uint8_t * lum_m3, uint8_t * lum_m2, - uint8_t * lum_m1, uint8_t * lum, int size); + GstDeinterlaceMethodVFIRClass *klass = + GST_DEINTERLACE_METHOD_VFIR_GET_CLASS (d_method); gint line = 0; uint8_t *cur_field, *last_field; uint8_t *t0, *b0, *tt1, *m1, *bb1, *out_data; -#ifdef HAVE_CPU_I386 - if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) { - func = deinterlace_line_mmx; - } else { - func = deinterlace_line_c; - } -#else - func = deinterlace_line_c; -#endif - cur_field = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf); last_field = @@ -173,7 +184,7 @@ deinterlace_frame_vfir (GstDeinterlace2 * object) bb1 = tt1; } - func (out_data, tt1, t0, m1, b0, bb1, object->line_length); + klass->scanline (out_data, tt1, t0, m1, b0, bb1, object->line_length); out_data += object->output_stride; cur_field += object->field_stride; last_field += object->field_stride; @@ -189,31 +200,33 @@ deinterlace_frame_vfir (GstDeinterlace2 * object) } } -static deinterlace_method_t vfirmethod = { - 0, //DEINTERLACE_PLUGIN_API_VERSION, - "Blur: Vertical", - "BlurVertical", - 2, - 0, - 0, - 0, - 0, - 1, - deinterlace_frame_vfir, - {"Avoids flicker by blurring consecutive frames", - "of input. Use this if you want to run your", - "monitor at an arbitrary refresh rate and not", - "use much CPU, and are willing to sacrifice", - "detail.", - "", - "Vertical mode blurs favouring the most recent", - "field for less visible trails. From the", - "deinterlacer filter in ffmpeg.", - ""} -}; - -deinterlace_method_t * -dscaler_vfir_get_method (void) +G_DEFINE_TYPE (GstDeinterlaceMethodVFIR, gst_deinterlace_method_vfir, + GST_TYPE_DEINTERLACE_METHOD); + +static void +gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass) +{ + GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass; + guint cpu_flags = oil_cpu_get_flags (); + + dim_class->fields_required = 2; + dim_class->deinterlace_frame = deinterlace_frame_vfir; + dim_class->name = "Blur Vertical"; + dim_class->nick = "vfir"; + dim_class->latency = 0; + +#ifdef HAVE_CPU_I386 + if (cpu_flags & OIL_IMPL_FLAG_MMX) { + klass->scanline = deinterlace_line_mmx; + } else { + klass->scanline = deinterlace_line_c; + } +#else + klass->scanline = deinterlace_line_c; +#endif +} + +static void +gst_deinterlace_method_vfir_init (GstDeinterlaceMethodVFIR * self) { - return &vfirmethod; } |