1 /*
2 * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
3 * Copyright (C) 2008,2010 Sebastian Dröge <slomo@collabora.co.uk>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 /*
22 * Relicensed for GStreamer from GPL to LGPL with permit from Tom Barry.
23 * See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
24 */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include <gst/gst.h>
34 #ifdef HAVE_ORC
35 #include <orc/orc.h>
36 #endif
37 #include "gstdeinterlacemethod.h"
38 #include "plugins.h"
39
40 #define GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP (gst_deinterlace_method_tomsmocomp_get_type ())
41 #define GST_IS_DEINTERLACE_METHOD_TOMSMOCOMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP))
42 #define GST_IS_DEINTERLACE_METHOD_TOMSMOCOMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP))
43 #define GST_DEINTERLACE_METHOD_TOMSMOCOMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoCompClass))
44 #define GST_DEINTERLACE_METHOD_TOMSMOCOMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoComp))
45 #define GST_DEINTERLACE_METHOD_TOMSMOCOMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_TOMSMOCOMP, GstDeinterlaceMethodTomsMoCompClass))
46 #define GST_DEINTERLACE_METHOD_TOMSMOCOMP_CAST(obj) ((GstDeinterlaceMethodTomsMoComp*)(obj))
47
48 typedef struct
49 {
50 GstDeinterlaceMethod parent;
51
52 guint search_effort;
53 gboolean strange_bob;
54 } GstDeinterlaceMethodTomsMoComp;
55
56 typedef GstDeinterlaceMethodClass GstDeinterlaceMethodTomsMoCompClass;
57
58 static void
Fieldcopy(guint8 * dest,const guint8 * src,gint count,gint rows,gint dst_pitch,gint src_pitch)59 Fieldcopy (guint8 * dest, const guint8 * src, gint count,
60 gint rows, gint dst_pitch, gint src_pitch)
61 {
62 gint i;
63
64 for (i = 0; i < rows; i++) {
65 memcpy (dest, src, count);
66 src += src_pitch;
67 dest += dst_pitch;
68 }
69 }
70
71 #define USE_FOR_DSCALER
72
73 #define IS_C
74 #define SIMD_TYPE C
75 #define FUNCT_NAME tomsmocompDScaler_C
76 #include "tomsmocomp/TomsMoCompAll.inc"
77 #undef IS_C
78 #undef SIMD_TYPE
79 #undef FUNCT_NAME
80
81 #ifdef BUILD_X86_ASM
82
83 #include "tomsmocomp/tomsmocompmacros.h"
84 #include "x86-64_macros.inc"
85
86 #define IS_MMX
87 #define SIMD_TYPE MMX
88 #define FUNCT_NAME tomsmocompDScaler_MMX
89 #include "tomsmocomp/TomsMoCompAll.inc"
90 #undef IS_MMX
91 #undef SIMD_TYPE
92 #undef FUNCT_NAME
93
94 #define IS_3DNOW
95 #define SIMD_TYPE 3DNOW
96 #define FUNCT_NAME tomsmocompDScaler_3DNOW
97 #include "tomsmocomp/TomsMoCompAll.inc"
98 #undef IS_3DNOW
99 #undef SIMD_TYPE
100 #undef FUNCT_NAME
101
102 #define IS_MMXEXT
103 #define SIMD_TYPE MMXEXT
104 #define FUNCT_NAME tomsmocompDScaler_MMXEXT
105 #include "tomsmocomp/TomsMoCompAll.inc"
106 #undef IS_MMXEXT
107 #undef SIMD_TYPE
108 #undef FUNCT_NAME
109
110 #endif
111
112 G_DEFINE_TYPE (GstDeinterlaceMethodTomsMoComp,
113 gst_deinterlace_method_tomsmocomp, GST_TYPE_DEINTERLACE_METHOD);
114
115 enum
116 {
117 PROP_0,
118 PROP_SEARCH_EFFORT,
119 PROP_STRANGE_BOB
120 };
121
122 static void
gst_deinterlace_method_tomsmocomp_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)123 gst_deinterlace_method_tomsmocomp_set_property (GObject * object, guint prop_id,
124 const GValue * value, GParamSpec * pspec)
125 {
126 GstDeinterlaceMethodTomsMoComp *self =
127 GST_DEINTERLACE_METHOD_TOMSMOCOMP (object);
128
129 switch (prop_id) {
130 case PROP_SEARCH_EFFORT:
131 self->search_effort = g_value_get_uint (value);
132 break;
133 case PROP_STRANGE_BOB:
134 self->strange_bob = g_value_get_boolean (value);
135 break;
136 default:
137 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
138 }
139 }
140
141 static void
gst_deinterlace_method_tomsmocomp_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)142 gst_deinterlace_method_tomsmocomp_get_property (GObject * object, guint prop_id,
143 GValue * value, GParamSpec * pspec)
144 {
145 GstDeinterlaceMethodTomsMoComp *self =
146 GST_DEINTERLACE_METHOD_TOMSMOCOMP (object);
147
148 switch (prop_id) {
149 case PROP_SEARCH_EFFORT:
150 g_value_set_uint (value, self->search_effort);
151 break;
152 case PROP_STRANGE_BOB:
153 g_value_set_boolean (value, self->strange_bob);
154 break;
155 default:
156 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
157 }
158 }
159
160 static void
gst_deinterlace_method_tomsmocomp_class_init(GstDeinterlaceMethodTomsMoCompClass * klass)161 gst_deinterlace_method_tomsmocomp_class_init
162 (GstDeinterlaceMethodTomsMoCompClass * klass)
163 {
164 GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
165 GObjectClass *gobject_class = (GObjectClass *) klass;
166 #ifdef BUILD_X86_ASM
167 guint cpu_flags =
168 orc_target_get_default_flags (orc_target_get_by_name ("mmx"));
169 #endif
170
171 gobject_class->set_property = gst_deinterlace_method_tomsmocomp_set_property;
172 gobject_class->get_property = gst_deinterlace_method_tomsmocomp_get_property;
173
174 g_object_class_install_property (gobject_class, PROP_SEARCH_EFFORT,
175 g_param_spec_uint ("search-effort",
176 "Search Effort",
177 "Search Effort", 0, 27, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
178 );
179
180 g_object_class_install_property (gobject_class, PROP_STRANGE_BOB,
181 g_param_spec_boolean ("strange-bob",
182 "Strange Bob",
183 "Use strange bob", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
184 );
185
186 dim_class->fields_required = 4;
187 dim_class->name = "Motion Adaptive: Motion Search";
188 dim_class->nick = "tomsmocomp";
189 dim_class->latency = 1;
190
191 #ifdef BUILD_X86_ASM
192 if (cpu_flags & ORC_TARGET_MMX_MMXEXT) {
193 dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_MMXEXT;
194 dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_MMXEXT;
195 } else if (cpu_flags & ORC_TARGET_MMX_3DNOW) {
196 dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_3DNOW;
197 dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_3DNOW;
198 } else if (cpu_flags & ORC_TARGET_MMX_MMX) {
199 dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_MMX;
200 dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_MMX;
201 } else {
202 dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_C;
203 dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_C;
204 }
205 #else
206 dim_class->deinterlace_frame_yuy2 = tomsmocompDScaler_C;
207 dim_class->deinterlace_frame_yvyu = tomsmocompDScaler_C;
208 #endif
209 }
210
211 static void
gst_deinterlace_method_tomsmocomp_init(GstDeinterlaceMethodTomsMoComp * self)212 gst_deinterlace_method_tomsmocomp_init (GstDeinterlaceMethodTomsMoComp * self)
213 {
214 self->search_effort = 5;
215 self->strange_bob = FALSE;
216 }
217