summaryrefslogtreecommitdiffstats
path: root/gst/deinterlace2/tvtime/greedy.c
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2008-07-05 16:47:32 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-07-05 16:47:32 +0000
commitd7c49f75d6dace82b2038a2a5c647822059dd6ed (patch)
treea5550cee43baa7ad41555c1c2b77ba36f17e60fd /gst/deinterlace2/tvtime/greedy.c
parent8fccf53fc2d070a4938ceb05b164f4a273388b20 (diff)
downloadgst-plugins-bad-d7c49f75d6dace82b2038a2a5c647822059dd6ed.tar.gz
gst-plugins-bad-d7c49f75d6dace82b2038a2a5c647822059dd6ed.tar.bz2
gst-plugins-bad-d7c49f75d6dace82b2038a2a5c647822059dd6ed.zip
gst/deinterlace2/: Use a GstObject subtype for the deinterlacing methods and export the different settings for each d...
Original commit message from CVS: * gst/deinterlace2/Makefile.am: * gst/deinterlace2/gstdeinterlace2.c: (gst_deinterlace_method_class_init), (gst_deinterlace_method_init), (gst_deinterlace_method_deinterlace_frame), (gst_deinterlace_method_get_fields_required), (gst_deinterlace2_methods_get_type), (_do_init), (gst_deinterlace2_set_method), (gst_deinterlace2_class_init), (gst_deinterlace2_child_proxy_get_child_by_index), (gst_deinterlace2_child_proxy_get_children_count), (gst_deinterlace2_child_proxy_interface_init), (gst_deinterlace2_init), (gst_deinterlace2_finalize), (gst_deinterlace2_chain), (gst_deinterlace2_src_query): * gst/deinterlace2/gstdeinterlace2.h: * gst/deinterlace2/tvtime/greedy.c: (deinterlace_greedy_packed422_scanline_c), (deinterlace_greedy_packed422_scanline_mmx), (deinterlace_greedy_packed422_scanline_mmxext), (deinterlace_frame_di_greedy), (gst_deinterlace_method_greedy_l_set_property), (gst_deinterlace_method_greedy_l_get_property), (gst_deinterlace_method_greedy_l_class_init), (gst_deinterlace_method_greedy_l_init): * gst/deinterlace2/tvtime/greedyh.asm: * gst/deinterlace2/tvtime/greedyh.c: (greedyDScaler_C), (deinterlace_frame_di_greedyh), (gst_deinterlace_method_greedy_h_set_property), (gst_deinterlace_method_greedy_h_get_property), (gst_deinterlace_method_greedy_h_class_init), (gst_deinterlace_method_greedy_h_init): * gst/deinterlace2/tvtime/greedyh.h: * gst/deinterlace2/tvtime/plugins.h: * gst/deinterlace2/tvtime/tomsmocomp.c: (gst_deinterlace_method_tomsmocomp_set_property), (gst_deinterlace_method_tomsmocomp_get_property), (gst_deinterlace_method_tomsmocomp_class_init), (gst_deinterlace_method_tomsmocomp_init): * gst/deinterlace2/tvtime/tomsmocomp.h: * gst/deinterlace2/tvtime/tomsmocomp/TomsMoCompAll.inc: * gst/deinterlace2/tvtime/vfir.c: (deinterlace_frame_vfir), (gst_deinterlace_method_vfir_class_init), (gst_deinterlace_method_vfir_init): Use a GstObject subtype for the deinterlacing methods and export the different settings for each deinterlacing method via GObject properties. Implement GstChildProxy interface to allow access to the used deinterlacing method and to allow adjusting the different settings. Move global variables of the tomsmocomp deinterlacing method into function local variables to make it possible to use this deinterlacing method from different instances.
Diffstat (limited to 'gst/deinterlace2/tvtime/greedy.c')
-rw-r--r--gst/deinterlace2/tvtime/greedy.c212
1 files changed, 142 insertions, 70 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;
}