| 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 | 55516 | 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 | 55516 | uint8_t *dst = dst1; | |
| 94 | 55516 | uint8_t *prev = prev1; | |
| 95 | 55516 | uint8_t *cur = cur1; | |
| 96 | 55516 | uint8_t *next = next1; | |
| 97 | int x; | ||
| 98 |
2/2✓ Branch 0 taken 38236 times.
✓ Branch 1 taken 17280 times.
|
55516 | uint8_t *prev2 = parity ? prev : cur ; |
| 99 |
2/2✓ Branch 0 taken 38236 times.
✓ Branch 1 taken 17280 times.
|
55516 | 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 4877434 times.
✓ Branch 1 taken 23104546 times.
✓ Branch 2 taken 2059945 times.
✓ Branch 3 taken 2817489 times.
✓ Branch 4 taken 4349195 times.
✓ Branch 5 taken 23632785 times.
✓ Branch 6 taken 1674750 times.
✓ Branch 7 taken 2674445 times.
✓ Branch 8 taken 27848400 times.
✓ Branch 9 taken 133580 times.
✓ Branch 10 taken 9837028 times.
✓ Branch 11 taken 18011372 times.
✓ Branch 12 taken 9837028 times.
✓ Branch 13 taken 18011372 times.
✓ Branch 14 taken 748362 times.
✓ Branch 15 taken 27233618 times.
✓ Branch 16 taken 1189628 times.
✓ Branch 17 taken 26043990 times.
✓ Branch 18 taken 27981980 times.
✓ Branch 19 taken 55516 times.
|
28037496 | FILTER(0, w, 1) |
| 106 | 55516 | } | |
| 107 | |||
| 108 | #define MAX_ALIGN 8 | ||
| 109 | 55516 | 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 | 55516 | uint8_t *dst = dst1; | |
| 113 | 55516 | uint8_t *prev = prev1; | |
| 114 | 55516 | uint8_t *cur = cur1; | |
| 115 | 55516 | uint8_t *next = next1; | |
| 116 | int x; | ||
| 117 |
2/2✓ Branch 0 taken 38236 times.
✓ Branch 1 taken 17280 times.
|
55516 | uint8_t *prev2 = parity ? prev : cur ; |
| 118 |
2/2✓ Branch 0 taken 38236 times.
✓ Branch 1 taken 17280 times.
|
55516 | uint8_t *next2 = parity ? cur : next; |
| 119 | |||
| 120 | 55516 | const int edge = MAX_ALIGN - 1; | |
| 121 | 55516 | 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 165450 times.
✓ Branch 1 taken 1098 times.
✓ Branch 2 taken 19724 times.
✓ Branch 3 taken 145726 times.
✓ Branch 4 taken 19724 times.
✓ Branch 5 taken 145726 times.
✓ Branch 6 taken 2838 times.
✓ Branch 7 taken 163710 times.
✓ Branch 8 taken 10845 times.
✓ Branch 9 taken 152865 times.
✓ Branch 10 taken 166548 times.
✓ Branch 11 taken 55516 times.
|
222064 | FILTER(0, FFMIN(3, w), 0) |
| 126 | |||
| 127 | 55516 | dst = (uint8_t*)dst1 + offset; | |
| 128 | 55516 | prev = (uint8_t*)prev1 + offset; | |
| 129 | 55516 | cur = (uint8_t*)cur1 + offset; | |
| 130 | 55516 | next = (uint8_t*)next1 + offset; | |
| 131 |
2/2✓ Branch 0 taken 38236 times.
✓ Branch 1 taken 17280 times.
|
55516 | prev2 = (uint8_t*)(parity ? prev : cur); |
| 132 |
2/2✓ Branch 0 taken 38236 times.
✓ Branch 1 taken 17280 times.
|
55516 | next2 = (uint8_t*)(parity ? cur : next); |
| 133 | |||
| 134 |
20/20✓ Branch 0 taken 2815 times.
✓ Branch 1 taken 219249 times.
✓ Branch 2 taken 795 times.
✓ Branch 3 taken 2020 times.
✓ Branch 4 taken 2875 times.
✓ Branch 5 taken 219189 times.
✓ Branch 6 taken 871 times.
✓ Branch 7 taken 2004 times.
✓ Branch 8 taken 220600 times.
✓ Branch 9 taken 1464 times.
✓ Branch 10 taken 35049 times.
✓ Branch 11 taken 185551 times.
✓ Branch 12 taken 35049 times.
✓ Branch 13 taken 185551 times.
✓ Branch 14 taken 7951 times.
✓ Branch 15 taken 214113 times.
✓ Branch 16 taken 30633 times.
✓ Branch 17 taken 183480 times.
✓ Branch 18 taken 222064 times.
✓ Branch 19 taken 55516 times.
|
277580 | FILTER(offset, w - 3, 1) |
| 135 |
1/2✓ Branch 0 taken 55516 times.
✗ Branch 1 not taken.
|
55516 | offset = FFMAX(offset, w - 3); |
| 136 |
12/12✓ Branch 0 taken 165450 times.
✓ Branch 1 taken 1098 times.
✓ Branch 2 taken 25970 times.
✓ Branch 3 taken 139480 times.
✓ Branch 4 taken 25970 times.
✓ Branch 5 taken 139480 times.
✓ Branch 6 taken 6078 times.
✓ Branch 7 taken 160470 times.
✓ Branch 8 taken 23535 times.
✓ Branch 9 taken 136935 times.
✓ Branch 10 taken 166548 times.
✓ Branch 11 taken 55516 times.
|
222064 | FILTER(offset, w, 0) |
| 137 | 55516 | } | |
| 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 | 4968 | static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | |
| 190 | { | ||
| 191 | 4968 | YADIFContext *s = ctx->priv; | |
| 192 | 4968 | ThreadData *td = arg; | |
| 193 | 4968 | int refs = s->cur->linesize[td->plane]; | |
| 194 | 4968 | int df = (s->csp->comp[td->plane].depth + 7) / 8; | |
| 195 | 4968 | int pix_3 = 3 * df; | |
| 196 | 4968 | int slice_start = (td->h * jobnr ) / nb_jobs; | |
| 197 | 4968 | int slice_end = (td->h * (jobnr+1)) / nb_jobs; | |
| 198 | int y; | ||
| 199 | 4968 | 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 182456 times.
✓ Branch 1 taken 4968 times.
|
187424 | for (y = slice_start; y < slice_end; y++) { |
| 205 |
2/2✓ Branch 0 taken 91228 times.
✓ Branch 1 taken 91228 times.
|
182456 | if ((y ^ td->parity) & 1) { |
| 206 | 91228 | uint8_t *prev = &s->prev->data[td->plane][y * refs]; | |
| 207 | 91228 | uint8_t *cur = &s->cur ->data[td->plane][y * refs]; | |
| 208 | 91228 | uint8_t *next = &s->next->data[td->plane][y * refs]; | |
| 209 | 91228 | uint8_t *dst = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]]; | |
| 210 |
4/4✓ Branch 0 taken 91138 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 90676 times.
✓ Branch 3 taken 462 times.
|
91228 | int mode = y == 1 || y + 2 == td->h ? 2 : s->mode; |
| 211 | 182456 | s->filter_line(dst + pix_3, prev + pix_3, cur + pix_3, | |
| 212 | 91228 | next + pix_3, td->w - edge, | |
| 213 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 91138 times.
|
91228 | y + 1 < td->h ? refs : -refs, |
| 214 | y ? -refs : refs, | ||
| 215 |
2/2✓ Branch 0 taken 90766 times.
✓ Branch 1 taken 462 times.
|
91228 | td->parity ^ td->tff, mode); |
| 216 | 182456 | s->filter_edges(dst, prev, cur, next, td->w, | |
| 217 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 91138 times.
|
91228 | y + 1 < td->h ? refs : -refs, |
| 218 | y ? -refs : refs, | ||
| 219 |
2/2✓ Branch 0 taken 90766 times.
✓ Branch 1 taken 462 times.
|
91228 | td->parity ^ td->tff, mode); |
| 220 | } else { | ||
| 221 | 91228 | memcpy(&td->frame->data[td->plane][y * td->frame->linesize[td->plane]], | |
| 222 | 91228 | &s->cur->data[td->plane][y * refs], td->w * df); | |
| 223 | } | ||
| 224 | } | ||
| 225 | 4968 | return 0; | |
| 226 | } | ||
| 227 | |||
| 228 | 184 | static void filter(AVFilterContext *ctx, AVFrame *dstpic, | |
| 229 | int parity, int tff) | ||
| 230 | { | ||
| 231 | 184 | YADIFContext *yadif = ctx->priv; | |
| 232 | 184 | ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff }; | |
| 233 | int i; | ||
| 234 | |||
| 235 |
2/2✓ Branch 0 taken 552 times.
✓ Branch 1 taken 184 times.
|
736 | for (i = 0; i < yadif->csp->nb_components; i++) { |
| 236 | 552 | int w = dstpic->width; | |
| 237 | 552 | int h = dstpic->height; | |
| 238 | |||
| 239 |
4/4✓ Branch 0 taken 368 times.
✓ Branch 1 taken 184 times.
✓ Branch 2 taken 184 times.
✓ Branch 3 taken 184 times.
|
552 | if (i == 1 || i == 2) { |
| 240 | 368 | w = AV_CEIL_RSHIFT(w, yadif->csp->log2_chroma_w); | |
| 241 | 368 | h = AV_CEIL_RSHIFT(h, yadif->csp->log2_chroma_h); | |
| 242 | } | ||
| 243 | |||
| 244 | |||
| 245 | 552 | td.w = w; | |
| 246 | 552 | td.h = h; | |
| 247 | 552 | td.plane = i; | |
| 248 | |||
| 249 | 552 | ff_filter_execute(ctx, filter_slice, &td, NULL, | |
| 250 |
1/2✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
|
552 | FFMIN(h, ff_filter_get_nb_threads(ctx))); |
| 251 | } | ||
| 252 | 184 | } | |
| 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 | 5 | static int config_output(AVFilterLink *outlink) | |
| 273 | { | ||
| 274 | 5 | AVFilterContext *ctx = outlink->src; | |
| 275 | 5 | YADIFContext *s = ctx->priv; | |
| 276 | int ret; | ||
| 277 | |||
| 278 | 5 | ret = ff_yadif_config_output_common(outlink); | |
| 279 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (ret < 0) |
| 280 | ✗ | return ret; | |
| 281 | |||
| 282 | 5 | s->csp = av_pix_fmt_desc_get(outlink->format); | |
| 283 | 5 | s->filter = filter; | |
| 284 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
|
5 | 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 | 3 | s->filter_line = filter_line_c; | |
| 289 | 3 | s->filter_edges = filter_edges; | |
| 290 | } | ||
| 291 | |||
| 292 | #if ARCH_X86 && HAVE_X86ASM | ||
| 293 | 5 | ff_yadif_init_x86(s); | |
| 294 | #endif | ||
| 295 | |||
| 296 | 5 | 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 |