FFmpeg
bwdifdsp.c
Go to the documentation of this file.
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, const 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  const uint8_t *cur = cur1;
123  int interpol, x;
124 
125  FILTER_INTRA()
126 }
127 
128 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  uint8_t *dst = dst1;
134  const uint8_t *prev = prev1;
135  const uint8_t *cur = cur1;
136  const uint8_t *next = next1;
137  const uint8_t *prev2 = parity ? prev : cur ;
138  const uint8_t *next2 = parity ? cur : next;
139  int interpol, x;
140 
141  FILTER1()
142  FILTER_LINE()
143  FILTER2()
144 }
145 
146 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  uint8_t *dst = dst1;
151  const uint8_t *prev = prev1;
152  const uint8_t *cur = cur1;
153  const uint8_t *next = next1;
154  const uint8_t *prev2 = parity ? prev : cur ;
155  const uint8_t *next2 = parity ? cur : next;
156  int interpol, x;
157 
158  FILTER1()
159  FILTER_EDGE()
160  FILTER2()
161 }
162 
163 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  uint16_t *dst = dst1;
167  const uint16_t *cur = cur1;
168  int interpol, x;
169 
170  FILTER_INTRA()
171 }
172 
173 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  uint16_t *dst = dst1;
179  const uint16_t *prev = prev1;
180  const uint16_t *cur = cur1;
181  const uint16_t *next = next1;
182  const uint16_t *prev2 = parity ? prev : cur ;
183  const uint16_t *next2 = parity ? cur : next;
184  int interpol, x;
185 
186  FILTER1()
187  FILTER_LINE()
188  FILTER2()
189 }
190 
191 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  uint16_t *dst = dst1;
196  const uint16_t *prev = prev1;
197  const uint16_t *cur = cur1;
198  const uint16_t *next = next1;
199  const uint16_t *prev2 = parity ? prev : cur ;
200  const uint16_t *next2 = parity ? cur : next;
201  int interpol, x;
202 
203  FILTER1()
204  FILTER_EDGE()
205  FILTER2()
206 }
207 
209 {
210  s->filter_line3 = 0;
211  if (bit_depth > 8) {
212  s->filter_intra = filter_intra_16bit;
213  s->filter_line = filter_line_c_16bit;
214  s->filter_edge = filter_edge_16bit;
215  } else {
216  s->filter_intra = ff_bwdif_filter_intra_c;
217  s->filter_line = ff_bwdif_filter_line_c;
218  s->filter_edge = ff_bwdif_filter_edge_c;
219  }
220 
221 #if ARCH_X86
223 #elif ARCH_AARCH64
225 #endif
226 }
ff_bwdif_filter_intra_c
void ff_bwdif_filter_intra_c(void *dst1, const void *cur1, int w, int prefs, int mrefs, int prefs3, int mrefs3, int parity, int clip_max)
Definition: bwdifdsp.c:118
interpol
static int interpol(MBContext *s, uint32_t *color, int x, int y, int linesize)
Definition: vsrc_mandelbrot.c:185
w
uint8_t w
Definition: llviddspenc.c:38
ff_bwdif_filter_edge_c
void ff_bwdif_filter_edge_c(void *dst1, const void *prev1, const void *cur1, const void *next1, int w, int prefs, int mrefs, int prefs2, int mrefs2, int parity, int clip_max, int spat)
Definition: bwdifdsp.c:146
FILTER1
#define FILTER1()
Definition: bwdifdsp.c:61
bit_depth
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition: af_astats.c:246
FILTER2
#define FILTER2()
Definition: bwdifdsp.c:101
ff_bwdif_init_filter_line
av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth)
Definition: bwdifdsp.c:208
macros.h
coef_sp
static const uint16_t coef_sp[2]
Definition: bwdifdsp.c:49
FILTER_INTRA
#define FILTER_INTRA()
Definition: bwdifdsp.c:52
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_bwdif_init_aarch64
void ff_bwdif_init_aarch64(BWDIFDSPContext *s, int bit_depth)
Definition: vf_bwdif_init_aarch64.c:110
filter_line_c_16bit
static void filter_line_c_16bit(void *dst1, const void *prev1, const void *cur1, const void *next1, int w, int prefs, int mrefs, int prefs2, int mrefs2, int prefs3, int mrefs3, int prefs4, int mrefs4, int parity, int clip_max)
Definition: bwdifdsp.c:173
filter_edge_16bit
static void filter_edge_16bit(void *dst1, const void *prev1, const void *cur1, const void *next1, int w, int prefs, int mrefs, int prefs2, int mrefs2, int parity, int clip_max, int spat)
Definition: bwdifdsp.c:191
BWDIFDSPContext
Definition: bwdifdsp.h:25
parity
mcdeint parity
Definition: vf_mcdeint.c:281
attributes.h
ff_bwdif_filter_line_c
void ff_bwdif_filter_line_c(void *dst1, const void *prev1, const void *cur1, const void *next1, int w, int prefs, int mrefs, int prefs2, int mrefs2, int prefs3, int mrefs3, int prefs4, int mrefs4, int parity, int clip_max)
Definition: bwdifdsp.c:128
common.h
filter_intra_16bit
static void filter_intra_16bit(void *dst1, const void *cur1, int w, int prefs, int mrefs, int prefs3, int mrefs3, int parity, int clip_max)
Definition: bwdifdsp.c:163
bwdifdsp.h
coef_hf
static const uint16_t coef_hf[3]
Definition: bwdifdsp.c:48
ff_bwdif_init_x86
void ff_bwdif_init_x86(BWDIFDSPContext *bwdif, int bit_depth)
Definition: vf_bwdif_init.c:53
FILTER_LINE
#define FILTER_LINE()
Definition: bwdifdsp.c:84
FILTER_EDGE
#define FILTER_EDGE()
Definition: bwdifdsp.c:95
coef_lf
static const uint16_t coef_lf[2]
Definition: bwdifdsp.c:47