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