1 /*
2 * Linear blend deinterlacing plugin. The idea for this algorithm came
3 * from the linear blend deinterlacer which originated in the mplayer
4 * sources.
5 *
6 * Copyright (C) 2002 Billy Biggs <vektor@dumbterm.net>.
7 * Copyright (C) 2008,2010 Sebastian Dröge <slomo@collabora.co.uk>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25 /*
26 * Relicensed for GStreamer from GPL to LGPL with permit from Billy Biggs.
27 * See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
28 */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include "gstdeinterlacemethod.h"
35 #include <string.h>
36 #ifdef HAVE_ORC
37 #include <orc/orc.h>
38 #endif
39 #include "tvtime.h"
40
41 #define GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND (gst_deinterlace_method_linear_blend_get_type ())
42 #define GST_IS_DEINTERLACE_METHOD_LINEAR_BLEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND))
43 #define GST_IS_DEINTERLACE_METHOD_LINEAR_BLEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND))
44 #define GST_DEINTERLACE_METHOD_LINEAR_BLEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND, GstDeinterlaceMethodLinearBlendClass))
45 #define GST_DEINTERLACE_METHOD_LINEAR_BLEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND, GstDeinterlaceMethodLinearBlend))
46 #define GST_DEINTERLACE_METHOD_LINEAR_BLEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_LINEAR_BLEND, GstDeinterlaceMethodLinearBlendClass))
47 #define GST_DEINTERLACE_METHOD_LINEAR_BLEND_CAST(obj) ((GstDeinterlaceMethodLinearBlend*)(obj))
48
49 GType gst_deinterlace_method_linear_blend_get_type (void);
50
51 typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodLinearBlend;
52 typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodLinearBlendClass;
53
54 static inline void
deinterlace_scanline_linear_blend_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const guint8 * t0,const guint8 * b0,const guint8 * m1,gint size)55 deinterlace_scanline_linear_blend_c (GstDeinterlaceSimpleMethod * self,
56 guint8 * out, const guint8 * t0, const guint8 * b0, const guint8 * m1,
57 gint size)
58 {
59 if (m1 == NULL) {
60 deinterlace_line_linear (out, t0, b0, size);
61 } else {
62 deinterlace_line_linear_blend (out, t0, b0, m1, size);
63 }
64 }
65
66 static void
deinterlace_scanline_linear_blend_packed_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const GstDeinterlaceScanlineData * scanlines,guint size)67 deinterlace_scanline_linear_blend_packed_c (GstDeinterlaceSimpleMethod * self,
68 guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size)
69 {
70 deinterlace_scanline_linear_blend_c (self, out, scanlines->t0, scanlines->b0,
71 scanlines->m1, size);
72 }
73
74 static void
deinterlace_scanline_linear_blend_planar_y_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const GstDeinterlaceScanlineData * scanlines,guint size)75 deinterlace_scanline_linear_blend_planar_y_c (GstDeinterlaceSimpleMethod * self,
76 guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size)
77 {
78 deinterlace_scanline_linear_blend_c (self, out, scanlines->t0, scanlines->b0,
79 scanlines->m1, size);
80 }
81
82 static void
deinterlace_scanline_linear_blend_planar_u_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const GstDeinterlaceScanlineData * scanlines,guint size)83 deinterlace_scanline_linear_blend_planar_u_c (GstDeinterlaceSimpleMethod * self,
84 guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size)
85 {
86 deinterlace_scanline_linear_blend_c (self, out, scanlines->t0, scanlines->b0,
87 scanlines->m1, size);
88 }
89
90 static void
deinterlace_scanline_linear_blend_planar_v_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const GstDeinterlaceScanlineData * scanlines,guint size)91 deinterlace_scanline_linear_blend_planar_v_c (GstDeinterlaceSimpleMethod * self,
92 guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size)
93 {
94 deinterlace_scanline_linear_blend_c (self, out, scanlines->t0, scanlines->b0,
95 scanlines->m1, size);
96 }
97
98 static inline void
deinterlace_scanline_linear_blend2_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const guint8 * m0,const guint8 * t1,const guint8 * b1,gint size)99 deinterlace_scanline_linear_blend2_c (GstDeinterlaceSimpleMethod * self,
100 guint8 * out, const guint8 * m0, const guint8 * t1, const guint8 * b1,
101 gint size)
102 {
103 if (t1 == NULL) {
104 memcpy (out, m0, size);
105 } else {
106 deinterlace_line_linear_blend (out, t1, b1, m0, size);
107 }
108 }
109
110 static void
deinterlace_scanline_linear_blend2_packed_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const GstDeinterlaceScanlineData * scanlines,guint size)111 deinterlace_scanline_linear_blend2_packed_c (GstDeinterlaceSimpleMethod * self,
112 guint8 * out, const GstDeinterlaceScanlineData * scanlines, guint size)
113 {
114 deinterlace_scanline_linear_blend2_c (self, out, scanlines->m0, scanlines->t1,
115 scanlines->b1, size);
116 }
117
118 static void
deinterlace_scanline_linear_blend2_planar_y_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const GstDeinterlaceScanlineData * scanlines,guint size)119 deinterlace_scanline_linear_blend2_planar_y_c (GstDeinterlaceSimpleMethod *
120 self, guint8 * out, const GstDeinterlaceScanlineData * scanlines,
121 guint size)
122 {
123 deinterlace_scanline_linear_blend2_c (self, out, scanlines->m0, scanlines->t1,
124 scanlines->b1, size);
125 }
126
127 static void
deinterlace_scanline_linear_blend2_planar_u_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const GstDeinterlaceScanlineData * scanlines,guint size)128 deinterlace_scanline_linear_blend2_planar_u_c (GstDeinterlaceSimpleMethod *
129 self, guint8 * out, const GstDeinterlaceScanlineData * scanlines,
130 guint size)
131 {
132 deinterlace_scanline_linear_blend2_c (self, out, scanlines->m0, scanlines->t1,
133 scanlines->b1, size);
134 }
135
136 static void
deinterlace_scanline_linear_blend2_planar_v_c(GstDeinterlaceSimpleMethod * self,guint8 * out,const GstDeinterlaceScanlineData * scanlines,guint size)137 deinterlace_scanline_linear_blend2_planar_v_c (GstDeinterlaceSimpleMethod *
138 self, guint8 * out, const GstDeinterlaceScanlineData * scanlines,
139 guint size)
140 {
141 deinterlace_scanline_linear_blend2_c (self, out, scanlines->m0, scanlines->t1,
142 scanlines->b1, size);
143 }
144
145 G_DEFINE_TYPE (GstDeinterlaceMethodLinearBlend,
146 gst_deinterlace_method_linear_blend, GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
147
148 static void
gst_deinterlace_method_linear_blend_class_init(GstDeinterlaceMethodLinearBlendClass * klass)149 gst_deinterlace_method_linear_blend_class_init
150 (GstDeinterlaceMethodLinearBlendClass * klass)
151 {
152 GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
153 GstDeinterlaceSimpleMethodClass *dism_class =
154 (GstDeinterlaceSimpleMethodClass *) klass;
155
156 dim_class->fields_required = 2;
157 dim_class->name = "Blur: Temporal";
158 dim_class->nick = "linearblend";
159 dim_class->latency = 1;
160
161 dism_class->interpolate_scanline_yuy2 =
162 deinterlace_scanline_linear_blend_packed_c;
163 dism_class->interpolate_scanline_yvyu =
164 deinterlace_scanline_linear_blend_packed_c;
165 dism_class->interpolate_scanline_uyvy =
166 deinterlace_scanline_linear_blend_packed_c;
167 dism_class->interpolate_scanline_ayuv =
168 deinterlace_scanline_linear_blend_packed_c;
169 dism_class->interpolate_scanline_argb =
170 deinterlace_scanline_linear_blend_packed_c;
171 dism_class->interpolate_scanline_rgba =
172 deinterlace_scanline_linear_blend_packed_c;
173 dism_class->interpolate_scanline_abgr =
174 deinterlace_scanline_linear_blend_packed_c;
175 dism_class->interpolate_scanline_bgra =
176 deinterlace_scanline_linear_blend_packed_c;
177 dism_class->interpolate_scanline_rgb =
178 deinterlace_scanline_linear_blend_packed_c;
179 dism_class->interpolate_scanline_bgr =
180 deinterlace_scanline_linear_blend_packed_c;
181 dism_class->interpolate_scanline_nv12 =
182 deinterlace_scanline_linear_blend_packed_c;
183 dism_class->interpolate_scanline_nv21 =
184 deinterlace_scanline_linear_blend_packed_c;
185
186 dism_class->interpolate_scanline_planar_y =
187 deinterlace_scanline_linear_blend_planar_y_c;
188 dism_class->interpolate_scanline_planar_u =
189 deinterlace_scanline_linear_blend_planar_u_c;
190 dism_class->interpolate_scanline_planar_v =
191 deinterlace_scanline_linear_blend_planar_v_c;
192
193 dism_class->copy_scanline_yuy2 = deinterlace_scanline_linear_blend2_packed_c;
194 dism_class->copy_scanline_yvyu = deinterlace_scanline_linear_blend2_packed_c;
195 dism_class->copy_scanline_uyvy = deinterlace_scanline_linear_blend2_packed_c;
196 dism_class->copy_scanline_ayuv = deinterlace_scanline_linear_blend2_packed_c;
197 dism_class->copy_scanline_argb = deinterlace_scanline_linear_blend2_packed_c;
198 dism_class->copy_scanline_abgr = deinterlace_scanline_linear_blend2_packed_c;
199 dism_class->copy_scanline_rgba = deinterlace_scanline_linear_blend2_packed_c;
200 dism_class->copy_scanline_bgra = deinterlace_scanline_linear_blend2_packed_c;
201 dism_class->copy_scanline_rgb = deinterlace_scanline_linear_blend2_packed_c;
202 dism_class->copy_scanline_bgr = deinterlace_scanline_linear_blend2_packed_c;
203
204 dism_class->copy_scanline_planar_y =
205 deinterlace_scanline_linear_blend2_planar_y_c;
206 dism_class->copy_scanline_planar_u =
207 deinterlace_scanline_linear_blend2_planar_u_c;
208 dism_class->copy_scanline_planar_v =
209 deinterlace_scanline_linear_blend2_planar_v_c;
210
211 }
212
213 static void
gst_deinterlace_method_linear_blend_init(GstDeinterlaceMethodLinearBlend * self)214 gst_deinterlace_method_linear_blend_init (GstDeinterlaceMethodLinearBlend *
215 self)
216 {
217 }
218