Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Copyright (C) 2006-2011 Michael Niedermayer <michaelni@gmx.at> | ||
3 | * 2010 James Darnley <james.darnley@gmail.com> | ||
4 | |||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #include "libavutil/common.h" | ||
23 | #include "libavutil/pixdesc.h" | ||
24 | #include "avfilter.h" | ||
25 | #include "filters.h" | ||
26 | #include "yadif.h" | ||
27 | |||
28 | typedef struct ThreadData { | ||
29 | AVFrame *frame; | ||
30 | int plane; | ||
31 | int w, h; | ||
32 | int parity; | ||
33 | int tff; | ||
34 | } ThreadData; | ||
35 | |||
36 | #define CHECK(j)\ | ||
37 | { int score = FFABS(cur[mrefs - 1 + (j)] - cur[prefs - 1 - (j)])\ | ||
38 | + FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\ | ||
39 | + FFABS(cur[mrefs + 1 + (j)] - cur[prefs + 1 - (j)]);\ | ||
40 | if (score < spatial_score) {\ | ||
41 | spatial_score= score;\ | ||
42 | spatial_pred= (cur[mrefs +(j)] + cur[prefs -(j)])>>1;\ | ||
43 | |||
44 | /* The is_not_edge argument here controls when the code will enter a branch | ||
45 | * which reads up to and including x-3 and x+3. */ | ||
46 | |||
47 | #define FILTER(start, end, is_not_edge) \ | ||
48 | for (x = start; x < end; x++) { \ | ||
49 | int c = cur[mrefs]; \ | ||
50 | int d = (prev2[0] + next2[0])>>1; \ | ||
51 | int e = cur[prefs]; \ | ||
52 | int temporal_diff0 = FFABS(prev2[0] - next2[0]); \ | ||
53 | int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1; \ | ||
54 | int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \ | ||
55 | int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \ | ||
56 | int spatial_pred = (c+e) >> 1; \ | ||
57 | \ | ||
58 | if (is_not_edge) {\ | ||
59 | int spatial_score = FFABS(cur[mrefs - 1] - cur[prefs - 1]) + FFABS(c-e) \ | ||
60 | + FFABS(cur[mrefs + 1] - cur[prefs + 1]) - 1; \ | ||
61 | CHECK(-1) CHECK(-2) }} }} \ | ||
62 | CHECK( 1) CHECK( 2) }} }} \ | ||
63 | }\ | ||
64 | \ | ||
65 | if (!(mode&2)) { \ | ||
66 | int b = (prev2[2 * mrefs] + next2[2 * mrefs])>>1; \ | ||
67 | int f = (prev2[2 * prefs] + next2[2 * prefs])>>1; \ | ||
68 | int max = FFMAX3(d - e, d - c, FFMIN(b - c, f - e)); \ | ||
69 | int min = FFMIN3(d - e, d - c, FFMAX(b - c, f - e)); \ | ||
70 | \ | ||
71 | diff = FFMAX3(diff, min, -max); \ | ||
72 | } \ | ||
73 | \ | ||
74 | if (spatial_pred > d + diff) \ | ||
75 | spatial_pred = d + diff; \ | ||
76 | else if (spatial_pred < d - diff) \ | ||
77 | spatial_pred = d - diff; \ | ||
78 | \ | ||
79 | dst[0] = spatial_pred; \ | ||
80 | \ | ||
81 | dst++; \ | ||
82 | cur++; \ | ||
83 | prev++; \ | ||
84 | next++; \ | ||
85 | prev2++; \ | ||
86 | next2++; \ | ||
87 | } | ||
88 | |||
89 | 52416 | static void filter_line_c(void *dst1, | |
90 | void *prev1, void *cur1, void *next1, | ||
91 | int w, int prefs, int mrefs, int parity, int mode) | ||
92 | { | ||
93 | 52416 | uint8_t *dst = dst1; | |
94 | 52416 | uint8_t *prev = prev1; | |
95 | 52416 | uint8_t *cur = cur1; | |
96 | 52416 | uint8_t *next = next1; | |
97 | int x; | ||
98 |
2/2✓ Branch 0 taken 35136 times.
✓ Branch 1 taken 17280 times.
|
52416 | uint8_t *prev2 = parity ? prev : cur ; |
99 |
2/2✓ Branch 0 taken 35136 times.
✓ Branch 1 taken 17280 times.
|
52416 | uint8_t *next2 = parity ? cur : next; |
100 | |||
101 | /* The function is called with the pointers already pointing to data[3] and | ||
102 | * with 6 subtracted from the width. This allows the FILTER macro to be | ||
103 | * called so that it processes all the pixels normally. A constant value of | ||
104 | * true for is_not_edge lets the compiler ignore the if statement. */ | ||
105 |
20/20✓ Branch 0 taken 4848793 times.
✓ Branch 1 taken 22931687 times.
✓ Branch 2 taken 2050336 times.
✓ Branch 3 taken 2798457 times.
✓ Branch 4 taken 4319393 times.
✓ Branch 5 taken 23461087 times.
✓ Branch 6 taken 1665425 times.
✓ Branch 7 taken 2653968 times.
✓ Branch 8 taken 27652170 times.
✓ Branch 9 taken 128310 times.
✓ Branch 10 taken 9768525 times.
✓ Branch 11 taken 17883645 times.
✓ Branch 12 taken 9768525 times.
✓ Branch 13 taken 17883645 times.
✓ Branch 14 taken 739587 times.
✓ Branch 15 taken 27040893 times.
✓ Branch 16 taken 1179529 times.
✓ Branch 17 taken 25861364 times.
✓ Branch 18 taken 27780480 times.
✓ Branch 19 taken 52416 times.
|
27832896 | FILTER(0, w, 1) |
106 | 52416 | } | |
107 | |||
108 | #define MAX_ALIGN 8 | ||
109 | 52416 | static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1, | |
110 | int w, int prefs, int mrefs, int parity, int mode) | ||
111 | { | ||
112 | 52416 | uint8_t *dst = dst1; | |
113 | 52416 | uint8_t *prev = prev1; | |
114 | 52416 | uint8_t *cur = cur1; | |
115 | 52416 | uint8_t *next = next1; | |
116 | int x; | ||
117 |
2/2✓ Branch 0 taken 35136 times.
✓ Branch 1 taken 17280 times.
|
52416 | uint8_t *prev2 = parity ? prev : cur ; |
118 |
2/2✓ Branch 0 taken 35136 times.
✓ Branch 1 taken 17280 times.
|
52416 | uint8_t *next2 = parity ? cur : next; |
119 | |||
120 | 52416 | const int edge = MAX_ALIGN - 1; | |
121 | 52416 | int offset = FFMAX(w - edge, 3); | |
122 | |||
123 | /* Only edge pixels need to be processed here. A constant value of false | ||
124 | * for is_not_edge should let the compiler ignore the whole branch. */ | ||
125 |
12/12✓ Branch 0 taken 156429 times.
✓ Branch 1 taken 819 times.
✓ Branch 2 taken 18381 times.
✓ Branch 3 taken 138048 times.
✓ Branch 4 taken 18381 times.
✓ Branch 5 taken 138048 times.
✓ Branch 6 taken 2675 times.
✓ Branch 7 taken 154573 times.
✓ Branch 8 taken 10202 times.
✓ Branch 9 taken 144371 times.
✓ Branch 10 taken 157248 times.
✓ Branch 11 taken 52416 times.
|
209664 | FILTER(0, FFMIN(3, w), 0) |
126 | |||
127 | 52416 | dst = (uint8_t*)dst1 + offset; | |
128 | 52416 | prev = (uint8_t*)prev1 + offset; | |
129 | 52416 | cur = (uint8_t*)cur1 + offset; | |
130 | 52416 | next = (uint8_t*)next1 + offset; | |
131 |
2/2✓ Branch 0 taken 35136 times.
✓ Branch 1 taken 17280 times.
|
52416 | prev2 = (uint8_t*)(parity ? prev : cur); |
132 |
2/2✓ Branch 0 taken 35136 times.
✓ Branch 1 taken 17280 times.
|
52416 | next2 = (uint8_t*)(parity ? cur : next); |
133 | |||
134 |
20/20✓ Branch 0 taken 1422 times.
✓ Branch 1 taken 208242 times.
✓ Branch 2 taken 322 times.
✓ Branch 3 taken 1100 times.
✓ Branch 4 taken 1054 times.
✓ Branch 5 taken 208610 times.
✓ Branch 6 taken 258 times.
✓ Branch 7 taken 796 times.
✓ Branch 8 taken 208572 times.
✓ Branch 9 taken 1092 times.
✓ Branch 10 taken 31452 times.
✓ Branch 11 taken 177120 times.
✓ Branch 12 taken 31452 times.
✓ Branch 13 taken 177120 times.
✓ Branch 14 taken 7566 times.
✓ Branch 15 taken 202098 times.
✓ Branch 16 taken 29970 times.
✓ Branch 17 taken 172128 times.
✓ Branch 18 taken 209664 times.
✓ Branch 19 taken 52416 times.
|
262080 | FILTER(offset, w - 3, 1) |
135 |
1/2✓ Branch 0 taken 52416 times.
✗ Branch 1 not taken.
|
52416 | offset = FFMAX(offset, w - 3); |
136 |
12/12✓ Branch 0 taken 156429 times.
✓ Branch 1 taken 819 times.
✓ Branch 2 taken 23325 times.
✓ Branch 3 taken 133104 times.
✓ Branch 4 taken 23325 times.
✓ Branch 5 taken 133104 times.
✓ Branch 6 taken 5766 times.
✓ Branch 7 taken 151482 times.
✓ Branch 8 taken 23141 times.
✓ Branch 9 taken 128341 times.
✓ Branch 10 taken 157248 times.
✓ Branch 11 taken 52416 times.
|
209664 | FILTER(offset, w, 0) |
137 | 52416 | } | |
138 | |||
139 | |||
140 | 35712 | static void filter_line_c_16bit(void *dst1, | |
141 | void *prev1, void *cur1, void *next1, | ||
142 | int w, int prefs, int mrefs, int parity, | ||
143 | int mode) | ||
144 | { | ||
145 | 35712 | uint16_t *dst = dst1; | |
146 | 35712 | uint16_t *prev = prev1; | |
147 | 35712 | uint16_t *cur = cur1; | |
148 | 35712 | uint16_t *next = next1; | |
149 | int x; | ||
150 |
1/2✓ Branch 0 taken 35712 times.
✗ Branch 1 not taken.
|
35712 | uint16_t *prev2 = parity ? prev : cur ; |
151 |
1/2✓ Branch 0 taken 35712 times.
✗ Branch 1 not taken.
|
35712 | uint16_t *next2 = parity ? cur : next; |
152 | 35712 | mrefs /= 2; | |
153 | 35712 | prefs /= 2; | |
154 | |||
155 |
20/20✓ Branch 0 taken 4170600 times.
✓ Branch 1 taken 14899608 times.
✓ Branch 2 taken 1671474 times.
✓ Branch 3 taken 2499126 times.
✓ Branch 4 taken 3583932 times.
✓ Branch 5 taken 15486276 times.
✓ Branch 6 taken 1305482 times.
✓ Branch 7 taken 2278450 times.
✓ Branch 8 taken 18982044 times.
✓ Branch 9 taken 88164 times.
✓ Branch 10 taken 6610940 times.
✓ Branch 11 taken 12371104 times.
✓ Branch 12 taken 6610940 times.
✓ Branch 13 taken 12371104 times.
✓ Branch 14 taken 774472 times.
✓ Branch 15 taken 18295736 times.
✓ Branch 16 taken 869794 times.
✓ Branch 17 taken 17425942 times.
✓ Branch 18 taken 19070208 times.
✓ Branch 19 taken 35712 times.
|
19105920 | FILTER(0, w, 1) |
156 | 35712 | } | |
157 | |||
158 | 35712 | static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1, | |
159 | int w, int prefs, int mrefs, int parity, int mode) | ||
160 | { | ||
161 | 35712 | uint16_t *dst = dst1; | |
162 | 35712 | uint16_t *prev = prev1; | |
163 | 35712 | uint16_t *cur = cur1; | |
164 | 35712 | uint16_t *next = next1; | |
165 | int x; | ||
166 |
1/2✓ Branch 0 taken 35712 times.
✗ Branch 1 not taken.
|
35712 | uint16_t *prev2 = parity ? prev : cur ; |
167 |
1/2✓ Branch 0 taken 35712 times.
✗ Branch 1 not taken.
|
35712 | uint16_t *next2 = parity ? cur : next; |
168 | |||
169 | 35712 | const int edge = MAX_ALIGN / 2 - 1; | |
170 | 35712 | int offset = FFMAX(w - edge, 3); | |
171 | |||
172 | 35712 | mrefs /= 2; | |
173 | 35712 | prefs /= 2; | |
174 | |||
175 |
12/12✓ Branch 0 taken 106578 times.
✓ Branch 1 taken 558 times.
✓ Branch 2 taken 13198 times.
✓ Branch 3 taken 93380 times.
✓ Branch 4 taken 13198 times.
✓ Branch 5 taken 93380 times.
✓ Branch 6 taken 2990 times.
✓ Branch 7 taken 104146 times.
✓ Branch 8 taken 5018 times.
✓ Branch 9 taken 99128 times.
✓ Branch 10 taken 107136 times.
✓ Branch 11 taken 35712 times.
|
142848 | FILTER(0, FFMIN(3, w), 0) |
176 | |||
177 | 35712 | dst = (uint16_t*)dst1 + offset; | |
178 | 35712 | prev = (uint16_t*)prev1 + offset; | |
179 | 35712 | cur = (uint16_t*)cur1 + offset; | |
180 | 35712 | next = (uint16_t*)next1 + offset; | |
181 |
1/2✓ Branch 0 taken 35712 times.
✗ Branch 1 not taken.
|
35712 | prev2 = (uint16_t*)(parity ? prev : cur); |
182 |
1/2✓ Branch 0 taken 35712 times.
✗ Branch 1 not taken.
|
35712 | next2 = (uint16_t*)(parity ? cur : next); |
183 | |||
184 |
1/20✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 35712 times.
|
35712 | FILTER(offset, w - 3, 1) |
185 |
1/2✓ Branch 0 taken 35712 times.
✗ Branch 1 not taken.
|
35712 | offset = FFMAX(offset, w - 3); |
186 |
12/12✓ Branch 0 taken 106578 times.
✓ Branch 1 taken 558 times.
✓ Branch 2 taken 17846 times.
✓ Branch 3 taken 88732 times.
✓ Branch 4 taken 17846 times.
✓ Branch 5 taken 88732 times.
✓ Branch 6 taken 5646 times.
✓ Branch 7 taken 101490 times.
✓ Branch 8 taken 13520 times.
✓ Branch 9 taken 87970 times.
✓ Branch 10 taken 107136 times.
✓ Branch 11 taken 35712 times.
|
142848 | FILTER(offset, w, 0) |
187 | 35712 | } | |
188 | |||
189 | 4131 | static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | |
190 | { | ||
191 | 4131 | YADIFContext *s = ctx->priv; | |
192 | 4131 | ThreadData *td = arg; | |
193 | 4131 | int refs = s->cur->linesize[td->plane]; | |
194 | 4131 | int df = (s->csp->comp[td->plane].depth + 7) / 8; | |
195 | 4131 | int pix_3 = 3 * df; | |
196 | 4131 | int slice_start = (td->h * jobnr ) / nb_jobs; | |
197 | 4131 | int slice_end = (td->h * (jobnr+1)) / nb_jobs; | |
198 | int y; | ||
199 | 4131 | int edge = 3 + MAX_ALIGN / df - 1; | |
200 | |||
201 | /* filtering reads 3 pixels to the left/right; to avoid invalid reads, | ||
202 | * we need to call the c variant which avoids this for border pixels | ||
203 | */ | ||
204 |
2/2✓ Branch 0 taken 176256 times.
✓ Branch 1 taken 4131 times.
|
180387 | for (y = slice_start; y < slice_end; y++) { |
205 |
2/2✓ Branch 0 taken 88128 times.
✓ Branch 1 taken 88128 times.
|
176256 | if ((y ^ td->parity) & 1) { |
206 | 88128 | uint8_t *prev = &s->prev->data[td->plane][y * refs]; | |
207 | 88128 | uint8_t *cur = &s->cur ->data[td->plane][y * refs]; | |
208 | 88128 | uint8_t *next = &s->next->data[td->plane][y * refs]; | |
209 | 88128 | uint8_t *dst = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]]; | |
210 |
4/4✓ Branch 0 taken 88038 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 87669 times.
✓ Branch 3 taken 369 times.
|
88128 | int mode = y == 1 || y + 2 == td->h ? 2 : s->mode; |
211 | 176256 | s->filter_line(dst + pix_3, prev + pix_3, cur + pix_3, | |
212 | 88128 | next + pix_3, td->w - edge, | |
213 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 88038 times.
|
88128 | y + 1 < td->h ? refs : -refs, |
214 | y ? -refs : refs, | ||
215 |
2/2✓ Branch 0 taken 87759 times.
✓ Branch 1 taken 369 times.
|
88128 | td->parity ^ td->tff, mode); |
216 | 176256 | s->filter_edges(dst, prev, cur, next, td->w, | |
217 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 88038 times.
|
88128 | y + 1 < td->h ? refs : -refs, |
218 | y ? -refs : refs, | ||
219 |
2/2✓ Branch 0 taken 87759 times.
✓ Branch 1 taken 369 times.
|
88128 | td->parity ^ td->tff, mode); |
220 | } else { | ||
221 | 88128 | memcpy(&td->frame->data[td->plane][y * td->frame->linesize[td->plane]], | |
222 | 88128 | &s->cur->data[td->plane][y * refs], td->w * df); | |
223 | } | ||
224 | } | ||
225 | 4131 | return 0; | |
226 | } | ||
227 | |||
228 | 153 | static void filter(AVFilterContext *ctx, AVFrame *dstpic, | |
229 | int parity, int tff) | ||
230 | { | ||
231 | 153 | YADIFContext *yadif = ctx->priv; | |
232 | 153 | ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff }; | |
233 | int i; | ||
234 | |||
235 |
2/2✓ Branch 0 taken 459 times.
✓ Branch 1 taken 153 times.
|
612 | for (i = 0; i < yadif->csp->nb_components; i++) { |
236 | 459 | int w = dstpic->width; | |
237 | 459 | int h = dstpic->height; | |
238 | |||
239 |
4/4✓ Branch 0 taken 306 times.
✓ Branch 1 taken 153 times.
✓ Branch 2 taken 153 times.
✓ Branch 3 taken 153 times.
|
459 | if (i == 1 || i == 2) { |
240 | 306 | w = AV_CEIL_RSHIFT(w, yadif->csp->log2_chroma_w); | |
241 | 306 | h = AV_CEIL_RSHIFT(h, yadif->csp->log2_chroma_h); | |
242 | } | ||
243 | |||
244 | |||
245 | 459 | td.w = w; | |
246 | 459 | td.h = h; | |
247 | 459 | td.plane = i; | |
248 | |||
249 | 459 | ff_filter_execute(ctx, filter_slice, &td, NULL, | |
250 |
1/2✓ Branch 0 taken 459 times.
✗ Branch 1 not taken.
|
459 | FFMIN(h, ff_filter_get_nb_threads(ctx))); |
251 | } | ||
252 | 153 | } | |
253 | |||
254 | static const enum AVPixelFormat pix_fmts[] = { | ||
255 | AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, | ||
256 | AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV440P, | ||
257 | AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, | ||
258 | AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, | ||
259 | AV_PIX_FMT_YUVJ440P, | ||
260 | AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, | ||
261 | AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, | ||
262 | AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, | ||
263 | AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, | ||
264 | AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, | ||
265 | AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, | ||
266 | AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, | ||
267 | AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, | ||
268 | AV_PIX_FMT_GBRAP, | ||
269 | AV_PIX_FMT_NONE | ||
270 | }; | ||
271 | |||
272 | 4 | static int config_output(AVFilterLink *outlink) | |
273 | { | ||
274 | 4 | AVFilterContext *ctx = outlink->src; | |
275 | 4 | YADIFContext *s = ctx->priv; | |
276 | int ret; | ||
277 | |||
278 | 4 | ret = ff_yadif_config_output_common(outlink); | |
279 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (ret < 0) |
280 | ✗ | return ret; | |
281 | |||
282 | 4 | s->csp = av_pix_fmt_desc_get(outlink->format); | |
283 | 4 | s->filter = filter; | |
284 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (s->csp->comp[0].depth > 8) { |
285 | 2 | s->filter_line = filter_line_c_16bit; | |
286 | 2 | s->filter_edges = filter_edges_16bit; | |
287 | } else { | ||
288 | 2 | s->filter_line = filter_line_c; | |
289 | 2 | s->filter_edges = filter_edges; | |
290 | } | ||
291 | |||
292 | #if ARCH_X86 | ||
293 | 4 | ff_yadif_init_x86(s); | |
294 | #endif | ||
295 | |||
296 | 4 | return 0; | |
297 | } | ||
298 | |||
299 | |||
300 | static const AVClass yadif_class = { | ||
301 | .class_name = "yadif", | ||
302 | .item_name = av_default_item_name, | ||
303 | .option = ff_yadif_options, | ||
304 | .version = LIBAVUTIL_VERSION_INT, | ||
305 | .category = AV_CLASS_CATEGORY_FILTER, | ||
306 | }; | ||
307 | |||
308 | static const AVFilterPad avfilter_vf_yadif_inputs[] = { | ||
309 | { | ||
310 | .name = "default", | ||
311 | .type = AVMEDIA_TYPE_VIDEO, | ||
312 | .filter_frame = ff_yadif_filter_frame, | ||
313 | }, | ||
314 | }; | ||
315 | |||
316 | static const AVFilterPad avfilter_vf_yadif_outputs[] = { | ||
317 | { | ||
318 | .name = "default", | ||
319 | .type = AVMEDIA_TYPE_VIDEO, | ||
320 | .request_frame = ff_yadif_request_frame, | ||
321 | .config_props = config_output, | ||
322 | }, | ||
323 | }; | ||
324 | |||
325 | const FFFilter ff_vf_yadif = { | ||
326 | .p.name = "yadif", | ||
327 | .p.description = NULL_IF_CONFIG_SMALL("Deinterlace the input image."), | ||
328 | .p.priv_class = &yadif_class, | ||
329 | .p.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, | ||
330 | .priv_size = sizeof(YADIFContext), | ||
331 | .uninit = ff_yadif_uninit, | ||
332 | FILTER_INPUTS(avfilter_vf_yadif_inputs), | ||
333 | FILTER_OUTPUTS(avfilter_vf_yadif_outputs), | ||
334 | FILTER_PIXFMTS_ARRAY(pix_fmts), | ||
335 | }; | ||
336 |