History

avfilter/vf_bwdif: Move DSP code to a new file

Otherwise checkasm/vf_bwdif.c pulls in vf_bwdif.c and then all of libavfilter. Besides being bad size-wise this also has the downside that it pulls in avpriv_(cga|vga16)_font from libavutil which are marked as being imported from another library when building libavfilter as a DLL and this breaks checkasm because it links both lavfi and lavu statically.

Andreas Rheinhardt committed 3 years ago

Commit 1db884c1 parent 80afcc83 files · +252 −212Browse files

Showing the changes to libavfilter (3 of 3 files). Show all

Unified · Split

3 files
  1. libavfilter/Makefile +1 −1
  2. libavfilter/bwdifdsp.c +251 −0
  3. libavfilter/vf_bwdif.c +0 −211
libavfilter/Makefile+1−1
@@ -214,7 +214,7 @@ OBJS-$(CONFIG_BM3D_FILTER) += vf_bm3d.o framesync.o · 213 unmodified lines
214214 OBJS-$(CONFIG_BOXBLUR_FILTER) += vf_boxblur.o boxblur.o
215215 OBJS-$(CONFIG_BOXBLUR_OPENCL_FILTER) += vf_avgblur_opencl.o opencl.o \
216216 opencl/avgblur.o boxblur.o
217−OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o yadif_common.o
217+OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o bwdifdsp.o yadif_common.o
218218 OBJS-$(CONFIG_BWDIF_CUDA_FILTER) += vf_bwdif_cuda.o vf_bwdif_cuda.ptx.o \
219219 yadif_common.o
220220 OBJS-$(CONFIG_BWDIF_VULKAN_FILTER) += vf_bwdif_vulkan.o yadif_common.o vulkan.o vulkan_filter.o
libavfilter/bwdifdsp.c+251−0
@@ -0,0 +1,251 @@
1+/*
2+ * BobWeaver Deinterlacing Filter DSP functions
3+ * Copyright (C) 2016 Thomas Mundt <loudmax@yahoo.de>
4+ *
5+ * Based on YADIF (Yet Another Deinterlacing Filter)
6+ * Copyright (C) 2006-2011 Michael Niedermayer <michaelni@gmx.at>
7+ * 2010 James Darnley <james.darnley@gmail.com>
8+ *
9+ * With use of Weston 3 Field Deinterlacing Filter algorithm
10+ * Copyright (C) 2012 British Broadcasting Corporation, All Rights Reserved
11+ * Author of de-interlace algorithm: Jim Easterbrook for BBC R&D
12+ * Based on the process described by Martin Weston for BBC R&D
13+ *
14+ * This file is part of FFmpeg.
15+ *
16+ * FFmpeg is free software; you can redistribute it and/or
17+ * modify it under the terms of the GNU Lesser General Public
18+ * License as published by the Free Software Foundation; either
19+ * version 2.1 of the License, or (at your option) any later version.
20+ *
21+ * FFmpeg is distributed in the hope that it will be useful,
22+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24+ * Lesser General Public License for more details.
25+ *
26+ * You should have received a copy of the GNU Lesser General Public
27+ * License along with FFmpeg; if not, write to the Free Software
28+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29+ */
30+
31+#include <stdint.h>
32+#include <string.h>
33+
34+#include "config.h"
35+
36+#include "bwdifdsp.h"
37+#include "libavutil/attributes.h"
38+#include "libavutil/common.h"
39+#include "libavutil/macros.h"
40+
41+/*
42+ * Filter coefficients coef_lf and coef_hf taken from BBC PH-2071 (Weston 3 Field Deinterlacer).
43+ * Used when there is spatial and temporal interpolation.
44+ * Filter coefficients coef_sp are used when there is spatial interpolation only.
45+ * Adjusted for matching visual sharpness impression of spatial and temporal interpolation.
46+ */
47+static const uint16_t coef_lf[2] = { 4309, 213 };
48+static const uint16_t coef_hf[3] = { 5570, 3801, 1016 };
49+static const uint16_t coef_sp[2] = { 5077, 981 };
50+
51+
52+#define FILTER_INTRA() \
53+ for (x = 0; x < w; x++) { \
54+ interpol = (coef_sp[0] * (cur[mrefs] + cur[prefs]) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
55+ dst[0] = av_clip(interpol, 0, clip_max); \
56+ \
57+ dst++; \
58+ cur++; \
59+ }
60+
61+#define FILTER1() \
62+ for (x = 0; x < w; x++) { \
63+ int c = cur[mrefs]; \
64+ int d = (prev2[0] + next2[0]) >> 1; \
65+ int e = cur[prefs]; \
66+ int temporal_diff0 = FFABS(prev2[0] - next2[0]); \
67+ int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e)) >> 1; \
68+ int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e)) >> 1; \
69+ int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \
70+ \
71+ if (!diff) { \
72+ dst[0] = d; \
73+ } else {
74+
75+#define SPAT_CHECK() \
76+ int b = ((prev2[mrefs2] + next2[mrefs2]) >> 1) - c; \
77+ int f = ((prev2[prefs2] + next2[prefs2]) >> 1) - e; \
78+ int dc = d - c; \
79+ int de = d - e; \
80+ int max = FFMAX3(de, dc, FFMIN(b, f)); \
81+ int min = FFMIN3(de, dc, FFMAX(b, f)); \
82+ diff = FFMAX3(diff, min, -max);
83+
84+#define FILTER_LINE() \
85+ SPAT_CHECK() \
86+ if (FFABS(c - e) > temporal_diff0) { \
87+ interpol = (((coef_hf[0] * (prev2[0] + next2[0]) \
88+ - coef_hf[1] * (prev2[mrefs2] + next2[mrefs2] + prev2[prefs2] + next2[prefs2]) \
89+ + coef_hf[2] * (prev2[mrefs4] + next2[mrefs4] + prev2[prefs4] + next2[prefs4])) >> 2) \
90+ + coef_lf[0] * (c + e) - coef_lf[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
91+ } else { \
92+ interpol = (coef_sp[0] * (c + e) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
93+ }
94+
95+#define FILTER_EDGE() \
96+ if (spat) { \
97+ SPAT_CHECK() \
98+ } \
99+ interpol = (c + e) >> 1;
100+
101+#define FILTER2() \
102+ if (interpol > d + diff) \
103+ interpol = d + diff; \
104+ else if (interpol < d - diff) \
105+ interpol = d - diff; \
106+ \
107+ dst[0] = av_clip(interpol, 0, clip_max); \
108+ } \
109+ \
110+ dst++; \
111+ cur++; \
112+ prev++; \
113+ next++; \
114+ prev2++; \
115+ next2++; \
116+ }
117+
118+void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs,
119+ int prefs3, int mrefs3, int parity, int clip_max)
120+{
121+ uint8_t *dst = dst1;
122+ uint8_t *cur = cur1;
123+ int interpol, x;
124+
125+ FILTER_INTRA()
126+}
127+
128+void ff_bwdif_filter_line_c(void *dst1, void *prev1, void *cur1, void *next1,
129+ int w, int prefs, int mrefs, int prefs2, int mrefs2,
130+ int prefs3, int mrefs3, int prefs4, int mrefs4,
131+ int parity, int clip_max)
132+{
133+ uint8_t *dst = dst1;
134+ uint8_t *prev = prev1;
135+ uint8_t *cur = cur1;
136+ uint8_t *next = next1;
137+ uint8_t *prev2 = parity ? prev : cur ;
138+ uint8_t *next2 = parity ? cur : next;
139+ int interpol, x;
140+
141+ FILTER1()
142+ FILTER_LINE()
143+ FILTER2()
144+}
145+
146+#define NEXT_LINE()\
147+ dst += d_stride; \
148+ prev += prefs; \
149+ cur += prefs; \
150+ next += prefs;
151+
152+void ff_bwdif_filter_line3_c(void * dst1, int d_stride,
153+ const void * prev1, const void * cur1, const void * next1, int s_stride,
154+ int w, int parity, int clip_max)
155+{
156+ const int prefs = s_stride;
157+ uint8_t * dst = dst1;
158+ const uint8_t * prev = prev1;
159+ const uint8_t * cur = cur1;
160+ const uint8_t * next = next1;
161+
162+ ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w,
163+ prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max);
164+ NEXT_LINE();
165+ memcpy(dst, cur, w);
166+ NEXT_LINE();
167+ ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w,
168+ prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max);
169+}
170+
171+void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1,
172+ int w, int prefs, int mrefs, int prefs2, int mrefs2,
173+ int parity, int clip_max, int spat)
174+{
175+ uint8_t *dst = dst1;
176+ uint8_t *prev = prev1;
177+ uint8_t *cur = cur1;
178+ uint8_t *next = next1;
179+ uint8_t *prev2 = parity ? prev : cur ;
180+ uint8_t *next2 = parity ? cur : next;
181+ int interpol, x;
182+
183+ FILTER1()
184+ FILTER_EDGE()
185+ FILTER2()
186+}
187+
188+static void filter_intra_16bit(void *dst1, void *cur1, int w, int prefs, int mrefs,
189+ int prefs3, int mrefs3, int parity, int clip_max)
190+{
191+ uint16_t *dst = dst1;
192+ uint16_t *cur = cur1;
193+ int interpol, x;
194+
195+ FILTER_INTRA()
196+}
197+
198+static void filter_line_c_16bit(void *dst1, void *prev1, void *cur1, void *next1,
199+ int w, int prefs, int mrefs, int prefs2, int mrefs2,
200+ int prefs3, int mrefs3, int prefs4, int mrefs4,
201+ int parity, int clip_max)
202+{
203+ uint16_t *dst = dst1;
204+ uint16_t *prev = prev1;
205+ uint16_t *cur = cur1;
206+ uint16_t *next = next1;
207+ uint16_t *prev2 = parity ? prev : cur ;
208+ uint16_t *next2 = parity ? cur : next;
209+ int interpol, x;
210+
211+ FILTER1()
212+ FILTER_LINE()
213+ FILTER2()
214+}
215+
216+static void filter_edge_16bit(void *dst1, void *prev1, void *cur1, void *next1,
217+ int w, int prefs, int mrefs, int prefs2, int mrefs2,
218+ int parity, int clip_max, int spat)
219+{
220+ uint16_t *dst = dst1;
221+ uint16_t *prev = prev1;
222+ uint16_t *cur = cur1;
223+ uint16_t *next = next1;
224+ uint16_t *prev2 = parity ? prev : cur ;
225+ uint16_t *next2 = parity ? cur : next;
226+ int interpol, x;
227+
228+ FILTER1()
229+ FILTER_EDGE()
230+ FILTER2()
231+}
232+
233+av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth)
234+{
235+ s->filter_line3 = 0;
236+ if (bit_depth > 8) {
237+ s->filter_intra = filter_intra_16bit;
238+ s->filter_line = filter_line_c_16bit;
239+ s->filter_edge = filter_edge_16bit;
240+ } else {
241+ s->filter_intra = ff_bwdif_filter_intra_c;
242+ s->filter_line = ff_bwdif_filter_line_c;
243+ s->filter_edge = ff_bwdif_filter_edge_c;
244+ }
245+
246+#if ARCH_X86
247+ ff_bwdif_init_x86(s, bit_depth);
248+#elif ARCH_AARCH64
249+ ff_bwdif_init_aarch64(s, bit_depth);
250+#endif
251+}
libavfilter/vf_bwdif.c+0−211
@@ -37,16 +37,6 @@ · 36 unmodified lines
3737 #include "internal.h"
3838 #include "yadif.h"
3939
40−/*
41− * Filter coefficients coef_lf and coef_hf taken from BBC PH-2071 (Weston 3 Field Deinterlacer).
42− * Used when there is spatial and temporal interpolation.
43− * Filter coefficients coef_sp are used when there is spatial interpolation only.
44− * Adjusted for matching visual sharpness impression of spatial and temporal interpolation.
45− */
46−static const uint16_t coef_lf[2] = { 4309, 213 };
47−static const uint16_t coef_hf[3] = { 5570, 3801, 1016 };
48−static const uint16_t coef_sp[2] = { 5077, 981 };
49−
5040 typedef struct BWDIFContext {
5141 YADIFContext yadif;
5242 BWDIFDSPContext dsp;
@@ -60,187 +50,6 @@ typedef struct ThreadData { · 7 unmodified lines
6050 int tff;
6151 } ThreadData;
6252
63−#define FILTER_INTRA() \
64− for (x = 0; x < w; x++) { \
65− interpol = (coef_sp[0] * (cur[mrefs] + cur[prefs]) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
66− dst[0] = av_clip(interpol, 0, clip_max); \
67− \
68− dst++; \
69− cur++; \
70− }
71−
72−#define FILTER1() \
73− for (x = 0; x < w; x++) { \
74− int c = cur[mrefs]; \
75− int d = (prev2[0] + next2[0]) >> 1; \
76− int e = cur[prefs]; \
77− int temporal_diff0 = FFABS(prev2[0] - next2[0]); \
78− int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e)) >> 1; \
79− int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e)) >> 1; \
80− int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \
81− \
82− if (!diff) { \
83− dst[0] = d; \
84− } else {
85−
86−#define SPAT_CHECK() \
87− int b = ((prev2[mrefs2] + next2[mrefs2]) >> 1) - c; \
88− int f = ((prev2[prefs2] + next2[prefs2]) >> 1) - e; \
89− int dc = d - c; \
90− int de = d - e; \
91− int max = FFMAX3(de, dc, FFMIN(b, f)); \
92− int min = FFMIN3(de, dc, FFMAX(b, f)); \
93− diff = FFMAX3(diff, min, -max);
94−
95−#define FILTER_LINE() \
96− SPAT_CHECK() \
97− if (FFABS(c - e) > temporal_diff0) { \
98− interpol = (((coef_hf[0] * (prev2[0] + next2[0]) \
99− - coef_hf[1] * (prev2[mrefs2] + next2[mrefs2] + prev2[prefs2] + next2[prefs2]) \
100− + coef_hf[2] * (prev2[mrefs4] + next2[mrefs4] + prev2[prefs4] + next2[prefs4])) >> 2) \
101− + coef_lf[0] * (c + e) - coef_lf[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
102− } else { \
103− interpol = (coef_sp[0] * (c + e) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \
104− }
105−
106−#define FILTER_EDGE() \
107− if (spat) { \
108− SPAT_CHECK() \
109− } \
110− interpol = (c + e) >> 1;
111−
112−#define FILTER2() \
113− if (interpol > d + diff) \
114− interpol = d + diff; \
115− else if (interpol < d - diff) \
116− interpol = d - diff; \
117− \
118− dst[0] = av_clip(interpol, 0, clip_max); \
119− } \
120− \
121− dst++; \
122− cur++; \
123− prev++; \
124− next++; \
125− prev2++; \
126− next2++; \
127− }
128−
129−void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs,
130− int prefs3, int mrefs3, int parity, int clip_max)
131−{
132− uint8_t *dst = dst1;
133− uint8_t *cur = cur1;
134− int interpol, x;
135−
136− FILTER_INTRA()
137−}
138−
139−void ff_bwdif_filter_line_c(void *dst1, void *prev1, void *cur1, void *next1,
140− int w, int prefs, int mrefs, int prefs2, int mrefs2,
141− int prefs3, int mrefs3, int prefs4, int mrefs4,
142− int parity, int clip_max)
143−{
144− uint8_t *dst = dst1;
145− uint8_t *prev = prev1;
146− uint8_t *cur = cur1;
147− uint8_t *next = next1;
148− uint8_t *prev2 = parity ? prev : cur ;
149− uint8_t *next2 = parity ? cur : next;
150− int interpol, x;
151−
152− FILTER1()
153− FILTER_LINE()
154− FILTER2()
155−}
156−
157−#define NEXT_LINE()\
158− dst += d_stride; \
159− prev += prefs; \
160− cur += prefs; \
161− next += prefs;
162−
163−void ff_bwdif_filter_line3_c(void * dst1, int d_stride,
164− const void * prev1, const void * cur1, const void * next1, int s_stride,
165− int w, int parity, int clip_max)
166−{
167− const int prefs = s_stride;
168− uint8_t * dst = dst1;
169− const uint8_t * prev = prev1;
170− const uint8_t * cur = cur1;
171− const uint8_t * next = next1;
172−
173− ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w,
174− prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max);
175− NEXT_LINE();
176− memcpy(dst, cur, w);
177− NEXT_LINE();
178− ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w,
179− prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max);
180−}
181−
182−void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1,
183− int w, int prefs, int mrefs, int prefs2, int mrefs2,
184− int parity, int clip_max, int spat)
185−{
186− uint8_t *dst = dst1;
187− uint8_t *prev = prev1;
188− uint8_t *cur = cur1;
189− uint8_t *next = next1;
190− uint8_t *prev2 = parity ? prev : cur ;
191− uint8_t *next2 = parity ? cur : next;
192− int interpol, x;
193−
194− FILTER1()
195− FILTER_EDGE()
196− FILTER2()
197−}
198−
199−static void filter_intra_16bit(void *dst1, void *cur1, int w, int prefs, int mrefs,
200− int prefs3, int mrefs3, int parity, int clip_max)
201−{
202− uint16_t *dst = dst1;
203− uint16_t *cur = cur1;
204− int interpol, x;
205−
206− FILTER_INTRA()
207−}
208−
209−static void filter_line_c_16bit(void *dst1, void *prev1, void *cur1, void *next1,
210− int w, int prefs, int mrefs, int prefs2, int mrefs2,
211− int prefs3, int mrefs3, int prefs4, int mrefs4,
212− int parity, int clip_max)
213−{
214− uint16_t *dst = dst1;
215− uint16_t *prev = prev1;
216− uint16_t *cur = cur1;
217− uint16_t *next = next1;
218− uint16_t *prev2 = parity ? prev : cur ;
219− uint16_t *next2 = parity ? cur : next;
220− int interpol, x;
221−
222− FILTER1()
223− FILTER_LINE()
224− FILTER2()
225−}
226−
227−static void filter_edge_16bit(void *dst1, void *prev1, void *cur1, void *next1,
228− int w, int prefs, int mrefs, int prefs2, int mrefs2,
229− int parity, int clip_max, int spat)
230−{
231− uint16_t *dst = dst1;
232− uint16_t *prev = prev1;
233− uint16_t *cur = cur1;
234− uint16_t *next = next1;
235− uint16_t *prev2 = parity ? prev : cur ;
236− uint16_t *next2 = parity ? cur : next;
237− int interpol, x;
238−
239− FILTER1()
240− FILTER_EDGE()
241− FILTER2()
242−}
243−
24453 // Round job start line down to multiple of 4 so that if filter_line3 exists
24554 // and the frame is a multiple of 4 high then filter_line will never be called
24655 static inline int job_start(const int jobnr, const int nb_jobs, const int h)
@@ -394,26 +203,6 @@ static int config_props(AVFilterLink *link) · 147 unmodified lines
394203 return 0;
395204 }
396205
397−av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth)
398−{
399− s->filter_line3 = 0;
400− if (bit_depth > 8) {
401− s->filter_intra = filter_intra_16bit;
402− s->filter_line = filter_line_c_16bit;
403− s->filter_edge = filter_edge_16bit;
404− } else {
405− s->filter_intra = ff_bwdif_filter_intra_c;
406− s->filter_line = ff_bwdif_filter_line_c;
407− s->filter_edge = ff_bwdif_filter_edge_c;
408− }
409−
410−#if ARCH_X86
411− ff_bwdif_init_x86(s, bit_depth);
412−#elif ARCH_AARCH64
413− ff_bwdif_init_aarch64(s, bit_depth);
414−#endif
415−}
416−
417206
418207 #define OFFSET(x) offsetof(YADIFContext, x)
419208 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t