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 | 51264 | 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 | 51264 | uint8_t *dst = dst1; | |
94 | 51264 | uint8_t *prev = prev1; | |
95 | 51264 | uint8_t *cur = cur1; | |
96 | 51264 | uint8_t *next = next1; | |
97 | int x; | ||
98 |
2/2✓ Branch 0 taken 34560 times.
✓ Branch 1 taken 16704 times.
|
51264 | uint8_t *prev2 = parity ? prev : cur ; |
99 |
2/2✓ Branch 0 taken 34560 times.
✓ Branch 1 taken 16704 times.
|
51264 | 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 4734614 times.
✓ Branch 1 taken 22435306 times.
✓ Branch 2 taken 2003369 times.
✓ Branch 3 taken 2731245 times.
✓ Branch 4 taken 4223488 times.
✓ Branch 5 taken 22946432 times.
✓ Branch 6 taken 1629829 times.
✓ Branch 7 taken 2593659 times.
✓ Branch 8 taken 27044430 times.
✓ Branch 9 taken 125490 times.
✓ Branch 10 taken 9547409 times.
✓ Branch 11 taken 17497021 times.
✓ Branch 12 taken 9547409 times.
✓ Branch 13 taken 17497021 times.
✓ Branch 14 taken 694319 times.
✓ Branch 15 taken 26475601 times.
✓ Branch 16 taken 1117491 times.
✓ Branch 17 taken 25358110 times.
✓ Branch 18 taken 27169920 times.
✓ Branch 19 taken 51264 times.
|
27221184 | FILTER(0, w, 1) |
106 | 51264 | } | |
107 | |||
108 | #define MAX_ALIGN 8 | ||
109 | 51264 | 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 | 51264 | uint8_t *dst = dst1; | |
113 | 51264 | uint8_t *prev = prev1; | |
114 | 51264 | uint8_t *cur = cur1; | |
115 | 51264 | uint8_t *next = next1; | |
116 | int x; | ||
117 |
2/2✓ Branch 0 taken 34560 times.
✓ Branch 1 taken 16704 times.
|
51264 | uint8_t *prev2 = parity ? prev : cur ; |
118 |
2/2✓ Branch 0 taken 34560 times.
✓ Branch 1 taken 16704 times.
|
51264 | uint8_t *next2 = parity ? cur : next; |
119 | |||
120 | 51264 | const int edge = MAX_ALIGN - 1; | |
121 | 51264 | 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 152991 times.
✓ Branch 1 taken 801 times.
✓ Branch 2 taken 17937 times.
✓ Branch 3 taken 135054 times.
✓ Branch 4 taken 17937 times.
✓ Branch 5 taken 135054 times.
✓ Branch 6 taken 2594 times.
✓ Branch 7 taken 151198 times.
✓ Branch 8 taken 9944 times.
✓ Branch 9 taken 141254 times.
✓ Branch 10 taken 153792 times.
✓ Branch 11 taken 51264 times.
|
205056 | FILTER(0, FFMIN(3, w), 0) |
126 | |||
127 | 51264 | dst = (uint8_t*)dst1 + offset; | |
128 | 51264 | prev = (uint8_t*)prev1 + offset; | |
129 | 51264 | cur = (uint8_t*)cur1 + offset; | |
130 | 51264 | next = (uint8_t*)next1 + offset; | |
131 |
2/2✓ Branch 0 taken 34560 times.
✓ Branch 1 taken 16704 times.
|
51264 | prev2 = (uint8_t*)(parity ? prev : cur); |
132 |
2/2✓ Branch 0 taken 34560 times.
✓ Branch 1 taken 16704 times.
|
51264 | next2 = (uint8_t*)(parity ? cur : next); |
133 | |||
134 |
20/20✓ Branch 0 taken 1385 times.
✓ Branch 1 taken 203671 times.
✓ Branch 2 taken 309 times.
✓ Branch 3 taken 1076 times.
✓ Branch 4 taken 1027 times.
✓ Branch 5 taken 204029 times.
✓ Branch 6 taken 246 times.
✓ Branch 7 taken 781 times.
✓ Branch 8 taken 203988 times.
✓ Branch 9 taken 1068 times.
✓ Branch 10 taken 30880 times.
✓ Branch 11 taken 173108 times.
✓ Branch 12 taken 30880 times.
✓ Branch 13 taken 173108 times.
✓ Branch 14 taken 7360 times.
✓ Branch 15 taken 197696 times.
✓ Branch 16 taken 29452 times.
✓ Branch 17 taken 168244 times.
✓ Branch 18 taken 205056 times.
✓ Branch 19 taken 51264 times.
|
256320 | FILTER(offset, w - 3, 1) |
135 |
1/2✓ Branch 0 taken 51264 times.
✗ Branch 1 not taken.
|
51264 | offset = FFMAX(offset, w - 3); |
136 |
12/12✓ Branch 0 taken 152991 times.
✓ Branch 1 taken 801 times.
✓ Branch 2 taken 22911 times.
✓ Branch 3 taken 130080 times.
✓ Branch 4 taken 22911 times.
✓ Branch 5 taken 130080 times.
✓ Branch 6 taken 5611 times.
✓ Branch 7 taken 148181 times.
✓ Branch 8 taken 22757 times.
✓ Branch 9 taken 125424 times.
✓ Branch 10 taken 153792 times.
✓ Branch 11 taken 51264 times.
|
205056 | FILTER(offset, w, 0) |
137 | 51264 | } | |
138 | |||
139 | |||
140 | 34560 | 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 | 34560 | uint16_t *dst = dst1; | |
146 | 34560 | uint16_t *prev = prev1; | |
147 | 34560 | uint16_t *cur = cur1; | |
148 | 34560 | uint16_t *next = next1; | |
149 | int x; | ||
150 |
1/2✓ Branch 0 taken 34560 times.
✗ Branch 1 not taken.
|
34560 | uint16_t *prev2 = parity ? prev : cur ; |
151 |
1/2✓ Branch 0 taken 34560 times.
✗ Branch 1 not taken.
|
34560 | uint16_t *next2 = parity ? cur : next; |
152 | 34560 | mrefs /= 2; | |
153 | 34560 | prefs /= 2; | |
154 | |||
155 |
20/20✓ Branch 0 taken 4027932 times.
✓ Branch 1 taken 14427108 times.
✓ Branch 2 taken 1614830 times.
✓ Branch 3 taken 2413102 times.
✓ Branch 4 taken 3466792 times.
✓ Branch 5 taken 14988248 times.
✓ Branch 6 taken 1263762 times.
✓ Branch 7 taken 2203030 times.
✓ Branch 8 taken 18369720 times.
✓ Branch 9 taken 85320 times.
✓ Branch 10 taken 6392668 times.
✓ Branch 11 taken 11977052 times.
✓ Branch 12 taken 6392668 times.
✓ Branch 13 taken 11977052 times.
✓ Branch 14 taken 671320 times.
✓ Branch 15 taken 17783720 times.
✓ Branch 16 taken 762436 times.
✓ Branch 17 taken 17021284 times.
✓ Branch 18 taken 18455040 times.
✓ Branch 19 taken 34560 times.
|
18489600 | FILTER(0, w, 1) |
156 | 34560 | } | |
157 | |||
158 | 34560 | 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 | 34560 | uint16_t *dst = dst1; | |
162 | 34560 | uint16_t *prev = prev1; | |
163 | 34560 | uint16_t *cur = cur1; | |
164 | 34560 | uint16_t *next = next1; | |
165 | int x; | ||
166 |
1/2✓ Branch 0 taken 34560 times.
✗ Branch 1 not taken.
|
34560 | uint16_t *prev2 = parity ? prev : cur ; |
167 |
1/2✓ Branch 0 taken 34560 times.
✗ Branch 1 not taken.
|
34560 | uint16_t *next2 = parity ? cur : next; |
168 | |||
169 | 34560 | const int edge = MAX_ALIGN / 2 - 1; | |
170 | 34560 | int offset = FFMAX(w - edge, 3); | |
171 | |||
172 | 34560 | mrefs /= 2; | |
173 | 34560 | prefs /= 2; | |
174 | |||
175 |
12/12✓ Branch 0 taken 103140 times.
✓ Branch 1 taken 540 times.
✓ Branch 2 taken 12770 times.
✓ Branch 3 taken 90370 times.
✓ Branch 4 taken 12770 times.
✓ Branch 5 taken 90370 times.
✓ Branch 6 taken 2822 times.
✓ Branch 7 taken 100858 times.
✓ Branch 8 taken 4714 times.
✓ Branch 9 taken 96144 times.
✓ Branch 10 taken 103680 times.
✓ Branch 11 taken 34560 times.
|
138240 | FILTER(0, FFMIN(3, w), 0) |
176 | |||
177 | 34560 | dst = (uint16_t*)dst1 + offset; | |
178 | 34560 | prev = (uint16_t*)prev1 + offset; | |
179 | 34560 | cur = (uint16_t*)cur1 + offset; | |
180 | 34560 | next = (uint16_t*)next1 + offset; | |
181 |
1/2✓ Branch 0 taken 34560 times.
✗ Branch 1 not taken.
|
34560 | prev2 = (uint16_t*)(parity ? prev : cur); |
182 |
1/2✓ Branch 0 taken 34560 times.
✗ Branch 1 not taken.
|
34560 | 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 34560 times.
|
34560 | FILTER(offset, w - 3, 1) |
185 |
1/2✓ Branch 0 taken 34560 times.
✗ Branch 1 not taken.
|
34560 | offset = FFMAX(offset, w - 3); |
186 |
12/12✓ Branch 0 taken 103140 times.
✓ Branch 1 taken 540 times.
✓ Branch 2 taken 17298 times.
✓ Branch 3 taken 85842 times.
✓ Branch 4 taken 17298 times.
✓ Branch 5 taken 85842 times.
✓ Branch 6 taken 5458 times.
✓ Branch 7 taken 98222 times.
✓ Branch 8 taken 13048 times.
✓ Branch 9 taken 85174 times.
✓ Branch 10 taken 103680 times.
✓ Branch 11 taken 34560 times.
|
138240 | FILTER(offset, w, 0) |
187 | 34560 | } | |
188 | |||
189 | 4023 | static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | |
190 | { | ||
191 | 4023 | YADIFContext *s = ctx->priv; | |
192 | 4023 | ThreadData *td = arg; | |
193 | 4023 | int refs = s->cur->linesize[td->plane]; | |
194 | 4023 | int df = (s->csp->comp[td->plane].depth + 7) / 8; | |
195 | 4023 | int pix_3 = 3 * df; | |
196 | 4023 | int slice_start = (td->h * jobnr ) / nb_jobs; | |
197 | 4023 | int slice_end = (td->h * (jobnr+1)) / nb_jobs; | |
198 | int y; | ||
199 | 4023 | 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 171648 times.
✓ Branch 1 taken 4023 times.
|
175671 | for (y = slice_start; y < slice_end; y++) { |
205 |
2/2✓ Branch 0 taken 85824 times.
✓ Branch 1 taken 85824 times.
|
171648 | if ((y ^ td->parity) & 1) { |
206 | 85824 | uint8_t *prev = &s->prev->data[td->plane][y * refs]; | |
207 | 85824 | uint8_t *cur = &s->cur ->data[td->plane][y * refs]; | |
208 | 85824 | uint8_t *next = &s->next->data[td->plane][y * refs]; | |
209 | 85824 | uint8_t *dst = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]]; | |
210 |
4/4✓ Branch 0 taken 85737 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 85377 times.
✓ Branch 3 taken 360 times.
|
85824 | int mode = y == 1 || y + 2 == td->h ? 2 : s->mode; |
211 | 171648 | s->filter_line(dst + pix_3, prev + pix_3, cur + pix_3, | |
212 | 85824 | next + pix_3, td->w - edge, | |
213 |
2/2✓ Branch 0 taken 87 times.
✓ Branch 1 taken 85737 times.
|
85824 | y + 1 < td->h ? refs : -refs, |
214 | y ? -refs : refs, | ||
215 |
2/2✓ Branch 0 taken 85464 times.
✓ Branch 1 taken 360 times.
|
85824 | td->parity ^ td->tff, mode); |
216 | 171648 | s->filter_edges(dst, prev, cur, next, td->w, | |
217 |
2/2✓ Branch 0 taken 87 times.
✓ Branch 1 taken 85737 times.
|
85824 | y + 1 < td->h ? refs : -refs, |
218 | y ? -refs : refs, | ||
219 |
2/2✓ Branch 0 taken 85464 times.
✓ Branch 1 taken 360 times.
|
85824 | td->parity ^ td->tff, mode); |
220 | } else { | ||
221 | 85824 | memcpy(&td->frame->data[td->plane][y * td->frame->linesize[td->plane]], | |
222 | 85824 | &s->cur->data[td->plane][y * refs], td->w * df); | |
223 | } | ||
224 | } | ||
225 | 4023 | return 0; | |
226 | } | ||
227 | |||
228 | 149 | static void filter(AVFilterContext *ctx, AVFrame *dstpic, | |
229 | int parity, int tff) | ||
230 | { | ||
231 | 149 | YADIFContext *yadif = ctx->priv; | |
232 | 149 | ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff }; | |
233 | int i; | ||
234 | |||
235 |
2/2✓ Branch 0 taken 447 times.
✓ Branch 1 taken 149 times.
|
596 | for (i = 0; i < yadif->csp->nb_components; i++) { |
236 | 447 | int w = dstpic->width; | |
237 | 447 | int h = dstpic->height; | |
238 | |||
239 |
4/4✓ Branch 0 taken 298 times.
✓ Branch 1 taken 149 times.
✓ Branch 2 taken 149 times.
✓ Branch 3 taken 149 times.
|
447 | if (i == 1 || i == 2) { |
240 | 298 | w = AV_CEIL_RSHIFT(w, yadif->csp->log2_chroma_w); | |
241 | 298 | h = AV_CEIL_RSHIFT(h, yadif->csp->log2_chroma_h); | |
242 | } | ||
243 | |||
244 | |||
245 | 447 | td.w = w; | |
246 | 447 | td.h = h; | |
247 | 447 | td.plane = i; | |
248 | |||
249 | 447 | ff_filter_execute(ctx, filter_slice, &td, NULL, | |
250 |
1/2✓ Branch 0 taken 447 times.
✗ Branch 1 not taken.
|
447 | FFMIN(h, ff_filter_get_nb_threads(ctx))); |
251 | } | ||
252 | 149 | } | |
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 AVFilter ff_vf_yadif = { | ||
326 | .name = "yadif", | ||
327 | .description = NULL_IF_CONFIG_SMALL("Deinterlace the input image."), | ||
328 | .priv_size = sizeof(YADIFContext), | ||
329 | .priv_class = &yadif_class, | ||
330 | .uninit = ff_yadif_uninit, | ||
331 | FILTER_INPUTS(avfilter_vf_yadif_inputs), | ||
332 | FILTER_OUTPUTS(avfilter_vf_yadif_outputs), | ||
333 | FILTER_PIXFMTS_ARRAY(pix_fmts), | ||
334 | .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, | ||
335 | }; | ||
336 |