summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
Diffstat (limited to 'gst')
-rw-r--r--gst/deinterlace2/Makefile.am1
-rw-r--r--gst/deinterlace2/gstdeinterlace2.c263
-rw-r--r--gst/deinterlace2/gstdeinterlace2.h52
-rw-r--r--gst/deinterlace2/tvtime/greedy.c212
-rw-r--r--gst/deinterlace2/tvtime/greedyh.asm11
-rw-r--r--gst/deinterlace2/tvtime/greedyh.c215
-rw-r--r--gst/deinterlace2/tvtime/greedyh.h45
-rw-r--r--gst/deinterlace2/tvtime/plugins.h14
-rw-r--r--gst/deinterlace2/tvtime/tomsmocomp.c162
-rw-r--r--gst/deinterlace2/tvtime/tomsmocomp.h56
-rw-r--r--gst/deinterlace2/tvtime/tomsmocomp/TomsMoCompAll.inc35
-rw-r--r--gst/deinterlace2/tvtime/vfir.c95
12 files changed, 700 insertions, 461 deletions
diff --git a/gst/deinterlace2/Makefile.am b/gst/deinterlace2/Makefile.am
index b8ed59e4..26952e2e 100644
--- a/gst/deinterlace2/Makefile.am
+++ b/gst/deinterlace2/Makefile.am
@@ -17,7 +17,6 @@ noinst_HEADERS = \
gstdeinterlace2.h \
tvtime/mmx.h \
tvtime/sse.h \
- tvtime/greedyh.h \
tvtime/greedyh.asm \
tvtime/greedyhmacros.h \
tvtime/plugins.h \
diff --git a/gst/deinterlace2/gstdeinterlace2.c b/gst/deinterlace2/gstdeinterlace2.c
index e42afaba..4103cfb6 100644
--- a/gst/deinterlace2/gstdeinterlace2.c
+++ b/gst/deinterlace2/gstdeinterlace2.c
@@ -1,7 +1,7 @@
/*
* GStreamer
* Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
- * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
+ * 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
@@ -49,25 +49,56 @@ enum
ARG_FIELD_LAYOUT
};
-#define GST_TYPE_DEINTERLACE2_METHOD (gst_deinterlace2_method_get_type ())
+G_DEFINE_TYPE (GstDeinterlaceMethod, gst_deinterlace_method, GST_TYPE_OBJECT);
+
+static void
+gst_deinterlace_method_class_init (GstDeinterlaceMethodClass * klass)
+{
+ klass->available = TRUE;
+}
+
+static void
+gst_deinterlace_method_init (GstDeinterlaceMethod * self)
+{
+
+}
+
+static void
+gst_deinterlace_method_deinterlace_frame (GstDeinterlaceMethod * self,
+ GstDeinterlace2 * object)
+{
+ GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
+
+ klass->deinterlace_frame (self, object);
+}
+
+static gint
+gst_deinterlace_method_get_fields_required (GstDeinterlaceMethod * self)
+{
+ GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
+
+ return klass->fields_required;
+}
+
+#define GST_TYPE_DEINTERLACE2_METHODS (gst_deinterlace2_methods_get_type ())
static GType
-gst_deinterlace2_method_get_type (void)
+gst_deinterlace2_methods_get_type (void)
{
- static GType deinterlace2_method_type = 0;
+ static GType deinterlace2_methods_type = 0;
- static const GEnumValue method_types[] = {
- {GST_DEINTERLACE2_TOM, "Toms Motion Compensation", "tomsmc"},
+ static const GEnumValue methods_types[] = {
+ {GST_DEINTERLACE2_TOMSMOCOMP, "Toms Motion Compensation", "tomsmocomp"},
{GST_DEINTERLACE2_GREEDY_H, "Greedy High Motion", "greedyh"},
{GST_DEINTERLACE2_GREEDY_L, "Greedy Low Motion", "greedyl"},
{GST_DEINTERLACE2_VFIR, "Vertical Blur", "vfir"},
{0, NULL, NULL},
};
- if (!deinterlace2_method_type) {
- deinterlace2_method_type =
- g_enum_register_static ("GstDeinterlace2Methods", method_types);
+ if (!deinterlace2_methods_type) {
+ deinterlace2_methods_type =
+ g_enum_register_static ("GstDeinterlace2Methods", methods_types);
}
- return deinterlace2_method_type;
+ return deinterlace2_methods_type;
}
#define GST_TYPE_DEINTERLACE2_FIELDS (gst_deinterlace2_fields_get_type ())
@@ -141,8 +172,66 @@ static const GstQueryType *gst_deinterlace2_src_query_types (GstPad * pad);
static void gst_deinterlace2_reset (GstDeinterlace2 * object);
-GST_BOILERPLATE (GstDeinterlace2, gst_deinterlace2, GstElement,
- GST_TYPE_ELEMENT);
+static void gst_deinterlace2_child_proxy_interface_init (gpointer g_iface,
+ gpointer iface_data);
+
+static void
+_do_init (GType object_type)
+{
+ const GInterfaceInfo child_proxy_interface_info = {
+ (GInterfaceInitFunc) gst_deinterlace2_child_proxy_interface_init,
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
+
+ g_type_add_interface_static (object_type, GST_TYPE_CHILD_PROXY,
+ &child_proxy_interface_info);
+}
+
+GST_BOILERPLATE_FULL (GstDeinterlace2, gst_deinterlace2, GstElement,
+ GST_TYPE_ELEMENT, _do_init);
+
+static void
+gst_deinterlace2_set_method (GstDeinterlace2 * object,
+ GstDeinterlace2Methods method)
+{
+
+ if (object->method) {
+ gst_child_proxy_child_removed (GST_OBJECT (object),
+ GST_OBJECT (object->method));
+ gst_object_unparent (GST_OBJECT (object->method));
+ object->method = NULL;
+ }
+
+ switch (method) {
+ case GST_DEINTERLACE2_TOMSMOCOMP:
+ object->method = g_object_new (GST_TYPE_DEINTERLACE_TOMSMOCOMP, NULL);
+ break;
+ case GST_DEINTERLACE2_GREEDY_H:
+ object->method = g_object_new (GST_TYPE_DEINTERLACE_GREEDY_H, NULL);
+ break;
+ case GST_DEINTERLACE2_GREEDY_L:
+ object->method = g_object_new (GST_TYPE_DEINTERLACE_GREEDY_L, NULL);
+ break;
+ case GST_DEINTERLACE2_VFIR:
+ object->method = g_object_new (GST_TYPE_DEINTERLACE_VFIR, NULL);
+ break;
+ default:
+ GST_WARNING ("Invalid Deinterlacer Method");
+ return;
+ }
+
+ object->method_id = method;
+
+ gst_object_set_name (GST_OBJECT (object->method), "method");
+ gst_object_set_parent (GST_OBJECT (object->method), GST_OBJECT (object));
+ gst_child_proxy_child_added (GST_OBJECT (object),
+ GST_OBJECT (object->method));
+
+ /* TODO: if current method requires less fields in the history,
+ pop the diff from field_history.
+ */
+}
static void
gst_deinterlace2_base_init (gpointer klass)
@@ -177,8 +266,9 @@ gst_deinterlace2_class_init (GstDeinterlace2Class * klass)
g_param_spec_enum ("method",
"Method",
"Deinterlace Method",
- GST_TYPE_DEINTERLACE2_METHOD,
- GST_DEINTERLACE2_TOM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
+ GST_TYPE_DEINTERLACE2_METHODS,
+ GST_DEINTERLACE2_TOMSMOCOMP,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
);
g_object_class_install_property (gobject_class, ARG_FIELDS,
@@ -202,6 +292,33 @@ gst_deinterlace2_class_init (GstDeinterlace2Class * klass)
GST_DEBUG_FUNCPTR (gst_deinterlace2_change_state);
}
+static GstObject *
+gst_deinterlace2_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
+ guint index)
+{
+ GstDeinterlace2 *self = GST_DEINTERLACE2 (child_proxy);
+
+ g_return_val_if_fail (index == 0, NULL);
+
+ return gst_object_ref (self->method);
+}
+
+static guint
+gst_deinterlace2_child_proxy_get_children_count (GstChildProxy * child_proxy)
+{
+ return 1;
+}
+
+static void
+gst_deinterlace2_child_proxy_interface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ GstChildProxyInterface *iface = g_iface;
+
+ iface->get_child_by_index = gst_deinterlace2_child_proxy_get_child_by_index;
+ iface->get_children_count = gst_deinterlace2_child_proxy_get_children_count;
+}
+
static void
gst_deinterlace2_init (GstDeinterlace2 * object, GstDeinterlace2Class * klass)
{
@@ -231,9 +348,7 @@ gst_deinterlace2_init (GstDeinterlace2 * object, GstDeinterlace2Class * klass)
gst_element_no_more_pads (GST_ELEMENT (object));
- object->cpu_feature_flags = oil_cpu_get_flags ();
-
- object->method = dscaler_tomsmocomp_get_method ();
+ gst_deinterlace2_set_method (object, GST_DEINTERLACE2_TOMSMOCOMP);
object->field_layout = GST_DEINTERLACE2_LAYOUT_AUTO;
object->fields = GST_DEINTERLACE2_ALL;
@@ -276,37 +391,6 @@ gst_deinterlace2_reset (GstDeinterlace2 * object)
}
static void
-gst_deinterlace2_set_method (GstDeinterlace2 * object,
- GstDeinterlace2Methods method)
-{
-
- switch (method) {
- case GST_DEINTERLACE2_TOM:
- object->method_id = method;
- object->method = dscaler_tomsmocomp_get_method ();
- break;
- case GST_DEINTERLACE2_GREEDY_H:
- object->method_id = method;
- object->method = dscaler_greedyh_get_method ();
- break;
- case GST_DEINTERLACE2_GREEDY_L:
- object->method_id = method;
- object->method = dscaler_greedyl_get_method ();
- break;
- case GST_DEINTERLACE2_VFIR:
- object->method_id = method;
- object->method = dscaler_vfir_get_method ();
- break;
- default:
- GST_WARNING ("Invalid Deinterlacer Method");
- }
-
- /* TODO: if current method requires less fields in the history,
- pop the diff from field_history.
- */
-}
-
-static void
gst_deinterlace2_set_property (GObject * _object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
@@ -367,7 +451,14 @@ gst_deinterlace2_get_property (GObject * _object, guint prop_id,
static void
gst_deinterlace2_finalize (GObject * object)
{
- gst_deinterlace2_reset (GST_DEINTERLACE2 (object));
+ GstDeinterlace2 *self = GST_DEINTERLACE2 (object);
+
+ gst_deinterlace2_reset (self);
+
+ if (self->method) {
+ gst_object_unparent (GST_OBJECT (self->method));
+ self->method = NULL;
+ }
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -456,6 +547,7 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
GstDeinterlace2 *object = NULL;
GstClockTime timestamp;
GstFlowReturn ret = GST_FLOW_OK;
+ gint fields_required = 0;
object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad));
@@ -464,9 +556,11 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
if (object->method != NULL) {
int cur_field_idx = 0;
+ fields_required =
+ gst_deinterlace_method_get_fields_required (object->method);
/* Not enough fields in the history */
- if (object->history_count < object->method->fields_required + 1) {
+ if (object->history_count < fields_required + 1) {
/* TODO: do bob or just forward frame */
GST_DEBUG ("HistoryCount=%d", object->history_count);
return GST_FLOW_OK;
@@ -479,7 +573,7 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
if (object->fields == GST_DEINTERLACE2_BF)
GST_DEBUG ("Bottom fields");
- cur_field_idx = object->history_count - object->method->fields_required;
+ cur_field_idx = object->history_count - fields_required;
if ((object->field_history[cur_field_idx].flags == PICTURE_INTERLACED_TOP
&& object->fields == GST_DEINTERLACE2_TF) ||
@@ -494,25 +588,23 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
return ret;
/* do magic calculus */
- if (object->method->deinterlace_frame != NULL) {
- object->method->deinterlace_frame (object);
+ gst_deinterlace_method_deinterlace_frame (object->method, object);
- buf = gst_deinterlace2_pop_history (object);
- timestamp = GST_BUFFER_TIMESTAMP (buf);
- gst_buffer_unref (buf);
+ buf = gst_deinterlace2_pop_history (object);
+ timestamp = GST_BUFFER_TIMESTAMP (buf);
+ gst_buffer_unref (buf);
- GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
+ GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
+ GST_BUFFER_DURATION (object->out_buf) =
+ GST_SECOND / object->frame_rate_d / object->frame_rate_n;
+ if (object->fields == GST_DEINTERLACE2_ALL)
GST_BUFFER_DURATION (object->out_buf) =
- GST_SECOND / object->frame_rate_d / object->frame_rate_n;
- if (object->fields == GST_DEINTERLACE2_ALL)
- GST_BUFFER_DURATION (object->out_buf) =
- GST_BUFFER_DURATION (object->out_buf) / 2;
-
- ret = gst_pad_push (object->srcpad, object->out_buf);
- object->out_buf = NULL;
- if (ret != GST_FLOW_OK)
- return ret;
- }
+ GST_BUFFER_DURATION (object->out_buf) / 2;
+
+ ret = gst_pad_push (object->srcpad, object->out_buf);
+ object->out_buf = NULL;
+ if (ret != GST_FLOW_OK)
+ return ret;
}
/* no calculation done: remove excess field */
else if (object->field_history[cur_field_idx].flags ==
@@ -522,7 +614,7 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
gst_buffer_unref (buf);
}
- cur_field_idx = object->history_count - object->method->fields_required;
+ cur_field_idx = object->history_count - fields_required;
/* deinterlace bottom_field */
if ((object->field_history[cur_field_idx].flags == PICTURE_INTERLACED_BOTTOM
@@ -538,26 +630,24 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
return ret;
/* do magic calculus */
- if (object->method->deinterlace_frame != NULL) {
- object->method->deinterlace_frame (object);
+ gst_deinterlace_method_deinterlace_frame (object->method, object);
- buf = gst_deinterlace2_pop_history (object);
- timestamp = GST_BUFFER_TIMESTAMP (buf);
- gst_buffer_unref (buf);
+ buf = gst_deinterlace2_pop_history (object);
+ timestamp = GST_BUFFER_TIMESTAMP (buf);
+ gst_buffer_unref (buf);
- GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
+ GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
+ GST_BUFFER_DURATION (object->out_buf) =
+ GST_SECOND / object->frame_rate_d / object->frame_rate_n;
+ if (object->fields == GST_DEINTERLACE2_ALL)
GST_BUFFER_DURATION (object->out_buf) =
- GST_SECOND / object->frame_rate_d / object->frame_rate_n;
- if (object->fields == GST_DEINTERLACE2_ALL)
- GST_BUFFER_DURATION (object->out_buf) =
- GST_BUFFER_DURATION (object->out_buf) / 2;
+ GST_BUFFER_DURATION (object->out_buf) / 2;
- ret = gst_pad_push (object->srcpad, object->out_buf);
- object->out_buf = NULL;
+ ret = gst_pad_push (object->srcpad, object->out_buf);
+ object->out_buf = NULL;
- if (ret != GST_FLOW_OK)
- return ret;
- }
+ if (ret != GST_FLOW_OK)
+ return ret;
}
/* no calculation done: remove excess field */
else if (object->field_history[cur_field_idx].flags ==
@@ -757,6 +847,11 @@ gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
if ((peer = gst_pad_get_peer (object->sinkpad))) {
if ((res = gst_pad_query (peer, query))) {
GstClockTime latency;
+ gint fields_required = 0;
+
+ if (object->method)
+ fields_required =
+ gst_deinterlace_method_get_fields_required (object->method);
gst_query_parse_latency (query, &live, &min, &max);
@@ -766,7 +861,7 @@ gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
/* add our own latency */
latency =
- gst_util_uint64_scale (object->method->fields_required *
+ gst_util_uint64_scale (fields_required *
GST_SECOND, object->frame_rate_d, object->frame_rate_n);
latency /= 2;
diff --git a/gst/deinterlace2/gstdeinterlace2.h b/gst/deinterlace2/gstdeinterlace2.h
index b312037c..815e04eb 100644
--- a/gst/deinterlace2/gstdeinterlace2.h
+++ b/gst/deinterlace2/gstdeinterlace2.h
@@ -1,7 +1,7 @@
/*
* GStreamer
* Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
- * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
+ * 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
@@ -45,29 +45,40 @@ G_BEGIN_DECLS
typedef struct _GstDeinterlace2 GstDeinterlace2;
typedef struct _GstDeinterlace2Class GstDeinterlace2Class;
-typedef struct deinterlace_setting_s deinterlace_setting_t;
-typedef struct deinterlace_method_s deinterlace_method_t;
+#define GST_TYPE_DEINTERLACE_METHOD (gst_deinterlace_method_get_type ())
+#define GST_IS_DEINTERLACE_METHOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD))
+#define GST_IS_DEINTERLACE_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD))
+#define GST_DEINTERLACE_METHOD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD, GstDeinterlaceMethodClass))
+#define GST_DEINTERLACE_METHOD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD, GstDeinterlaceMethod))
+#define GST_DEINTERLACE_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD, GstDeinterlaceMethodClass))
+#define GST_DEINTERLACE_METHOD_CAST(obj) ((GstDeinterlaceMethod*)(obj))
-typedef void (*deinterlace_frame_t) (GstDeinterlace2 * object);
+typedef struct _GstDeinterlaceMethod GstDeinterlaceMethod;
+typedef struct _GstDeinterlaceMethodClass GstDeinterlaceMethodClass;
/*
* This structure defines the deinterlacer plugin.
*/
-struct deinterlace_method_s
-{
- int version;
- const char *name;
- const char *short_name;
- int fields_required;
- int accelrequired;
- int doscalerbob;
- int numsettings;
- deinterlace_setting_t *settings;
- int scanlinemode;
- deinterlace_frame_t deinterlace_frame;
- const char *description[10];
+
+struct _GstDeinterlaceMethod {
+ GstObject parent;
};
+struct _GstDeinterlaceMethodClass {
+ GstObjectClass parent_class;
+ guint fields_required;
+ guint latency;
+
+ gboolean available;
+
+ void (*deinterlace_frame) (GstDeinterlaceMethod *self, GstDeinterlace2 * object);
+
+ const gchar *name;
+ const gchar *nick;
+};
+
+GType gst_deinterlace_method_get_type (void);
+
#define MAX_FIELD_HISTORY 10
#define PICTURE_PROGRESSIVE 0
@@ -75,8 +86,6 @@ struct deinterlace_method_s
#define PICTURE_INTERLACED_TOP 2
#define PICTURE_INTERLACED_MASK (PICTURE_INTERLACED_BOTTOM | PICTURE_INTERLACED_TOP)
-typedef void (MEMCPY_FUNC) (void *pOutput, const void *pInput, size_t nSize);
-
typedef struct
{
/* pointer to the start of data for this field */
@@ -87,7 +96,7 @@ typedef struct
typedef enum
{
- GST_DEINTERLACE2_TOM,
+ GST_DEINTERLACE2_TOMSMOCOMP,
GST_DEINTERLACE2_GREEDY_H,
GST_DEINTERLACE2_GREEDY_L,
GST_DEINTERLACE2_VFIR
@@ -115,7 +124,6 @@ struct _GstDeinterlace2
guint history_count;
- guint cpu_feature_flags;
GstDeinterlace2FieldLayout field_layout;
guint frame_size;
@@ -124,7 +132,7 @@ struct _GstDeinterlace2
GstDeinterlace2Fields fields;
GstDeinterlace2Methods method_id;
- deinterlace_method_t *method;
+ GstDeinterlaceMethod *method;
/* The most recent pictures
PictureHistory[0] is always the most recent.
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;
}