FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/bwdifdsp.c
Date: 2024-05-03 15:42:48
Exec Total Coverage
Lines: 65 65 100.0%
Functions: 7 7 100.0%
Branches: 60 62 96.8%

Line Branch Exec Source
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 1154 void ff_bwdif_filter_intra_c(void *dst1, const void *cur1, int w, int prefs, int mrefs,
119 int prefs3, int mrefs3, int parity, int clip_max)
120 {
121 1154 uint8_t *dst = dst1;
122 1154 const uint8_t *cur = cur1;
123 int interpol, x;
124
125
2/2
✓ Branch 0 taken 622592 times.
✓ Branch 1 taken 1154 times.
623746 FILTER_INTRA()
126 1154 }
127
128 49083 void ff_bwdif_filter_line_c(void *dst1, const void *prev1, const void *cur1, const 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 49083 uint8_t *dst = dst1;
134 49083 const uint8_t *prev = prev1;
135 49083 const uint8_t *cur = cur1;
136 49083 const uint8_t *next = next1;
137
2/2
✓ Branch 0 taken 32716 times.
✓ Branch 1 taken 16367 times.
49083 const uint8_t *prev2 = parity ? prev : cur ;
138
2/2
✓ Branch 0 taken 32716 times.
✓ Branch 1 taken 16367 times.
49083 const uint8_t *next2 = parity ? cur : next;
139 int interpol, x;
140
141
4/4
✓ Branch 0 taken 3329215 times.
✓ Branch 1 taken 23233985 times.
✓ Branch 2 taken 26563200 times.
✓ Branch 3 taken 49083 times.
26612283 FILTER1()
142
2/2
✓ Branch 0 taken 5360370 times.
✓ Branch 1 taken 17873615 times.
23233985 FILTER_LINE()
143
4/4
✓ Branch 0 taken 486183 times.
✓ Branch 1 taken 22747802 times.
✓ Branch 2 taken 1077681 times.
✓ Branch 3 taken 21670121 times.
26563200 FILTER2()
144 49083 }
145
146 1052 void ff_bwdif_filter_edge_c(void *dst1, const void *prev1, const void *cur1, const void *next1,
147 int w, int prefs, int mrefs, int prefs2, int mrefs2,
148 int parity, int clip_max, int spat)
149 {
150 1052 uint8_t *dst = dst1;
151 1052 const uint8_t *prev = prev1;
152 1052 const uint8_t *cur = cur1;
153 1052 const uint8_t *next = next1;
154
2/2
✓ Branch 0 taken 700 times.
✓ Branch 1 taken 352 times.
1052 const uint8_t *prev2 = parity ? prev : cur ;
155
2/2
✓ Branch 0 taken 700 times.
✓ Branch 1 taken 352 times.
1052 const uint8_t *next2 = parity ? cur : next;
156 int interpol, x;
157
158
4/4
✓ Branch 0 taken 64240 times.
✓ Branch 1 taken 438928 times.
✓ Branch 2 taken 503168 times.
✓ Branch 3 taken 1052 times.
504220 FILTER1()
159
2/2
✓ Branch 0 taken 217805 times.
✓ Branch 1 taken 221123 times.
438928 FILTER_EDGE()
160
4/4
✓ Branch 0 taken 38843 times.
✓ Branch 1 taken 400085 times.
✓ Branch 2 taken 34113 times.
✓ Branch 3 taken 365972 times.
503168 FILTER2()
161 1052 }
162
163 576 static void filter_intra_16bit(void *dst1, const void *cur1, int w, int prefs, int mrefs,
164 int prefs3, int mrefs3, int parity, int clip_max)
165 {
166 576 uint16_t *dst = dst1;
167 576 const uint16_t *cur = cur1;
168 int interpol, x;
169
170
2/2
✓ Branch 0 taken 311040 times.
✓ Branch 1 taken 576 times.
311616 FILTER_INTRA()
171 576 }
172
173 16359 static void filter_line_c_16bit(void *dst1, const void *prev1, const void *cur1, const void *next1,
174 int w, int prefs, int mrefs, int prefs2, int mrefs2,
175 int prefs3, int mrefs3, int prefs4, int mrefs4,
176 int parity, int clip_max)
177 {
178 16359 uint16_t *dst = dst1;
179 16359 const uint16_t *prev = prev1;
180 16359 const uint16_t *cur = cur1;
181 16359 const uint16_t *next = next1;
182
2/2
✓ Branch 0 taken 16356 times.
✓ Branch 1 taken 3 times.
16359 const uint16_t *prev2 = parity ? prev : cur ;
183
2/2
✓ Branch 0 taken 16356 times.
✓ Branch 1 taken 3 times.
16359 const uint16_t *next2 = parity ? cur : next;
184 int interpol, x;
185
186
4/4
✓ Branch 0 taken 579766 times.
✓ Branch 1 taken 8274122 times.
✓ Branch 2 taken 8853888 times.
✓ Branch 3 taken 16359 times.
8870247 FILTER1()
187
2/2
✓ Branch 0 taken 1322586 times.
✓ Branch 1 taken 6951536 times.
8274122 FILTER_LINE()
188
4/4
✓ Branch 0 taken 299568 times.
✓ Branch 1 taken 7974554 times.
✓ Branch 2 taken 476921 times.
✓ Branch 3 taken 7497633 times.
8853888 FILTER2()
189 16359 }
190
191 348 static void filter_edge_16bit(void *dst1, const void *prev1, const void *cur1, const void *next1,
192 int w, int prefs, int mrefs, int prefs2, int mrefs2,
193 int parity, int clip_max, int spat)
194 {
195 348 uint16_t *dst = dst1;
196 348 const uint16_t *prev = prev1;
197 348 const uint16_t *cur = cur1;
198 348 const uint16_t *next = next1;
199
1/2
✓ Branch 0 taken 348 times.
✗ Branch 1 not taken.
348 const uint16_t *prev2 = parity ? prev : cur ;
200
1/2
✓ Branch 0 taken 348 times.
✗ Branch 1 not taken.
348 const uint16_t *next2 = parity ? cur : next;
201 int interpol, x;
202
203
4/4
✓ Branch 0 taken 13419 times.
✓ Branch 1 taken 153621 times.
✓ Branch 2 taken 167040 times.
✓ Branch 3 taken 348 times.
167388 FILTER1()
204
2/2
✓ Branch 0 taken 77332 times.
✓ Branch 1 taken 76289 times.
153621 FILTER_EDGE()
205
4/4
✓ Branch 0 taken 28609 times.
✓ Branch 1 taken 125012 times.
✓ Branch 2 taken 12604 times.
✓ Branch 3 taken 112408 times.
167040 FILTER2()
206 348 }
207
208 29 av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth)
209 {
210 29 s->filter_line3 = 0;
211
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 15 times.
29 if (bit_depth > 8) {
212 14 s->filter_intra = filter_intra_16bit;
213 14 s->filter_line = filter_line_c_16bit;
214 14 s->filter_edge = filter_edge_16bit;
215 } else {
216 15 s->filter_intra = ff_bwdif_filter_intra_c;
217 15 s->filter_line = ff_bwdif_filter_line_c;
218 15 s->filter_edge = ff_bwdif_filter_edge_c;
219 }
220
221 #if ARCH_X86
222 29 ff_bwdif_init_x86(s, bit_depth);
223 #elif ARCH_AARCH64
224 ff_bwdif_init_aarch64(s, bit_depth);
225 #endif
226 29 }
227