FFmpeg
Loading...
Searching...
No Matches
vf_xbr.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * Copyright (c) 2011, 2012 Hyllian/Jararaca <sergiogdb@gmail.com>
5 * Copyright (c) 2014 Arwa Arif <arwaarif1994@gmail.com>
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/**
23 * @file
24 * XBR Filter is used for depixelization of image.
25 * This is based on Hyllian's xBR shader.
26 *
27 * @see https://forums.libretro.com/t/xbr-algorithm-tutorial/123
28 * @see https://github.com/yoyofr/iFBA/blob/master/fba_src/src/intf/video/scalers/xbr.cpp
29 */
30
31#include "libavutil/opt.h"
32#include "libavutil/pixdesc.h"
33
34#include "filters.h"
35#include "video.h"
36
37#define LB_MASK 0x00FEFEFE
38#define RED_BLUE_MASK 0x00FF00FF
39#define GREEN_MASK 0x0000FF00
40
41#ifdef PI
42#undef PI
43#endif
44
45typedef int (*xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
46
47typedef struct XBRContext {
48 const AVClass *class;
49 int n;
51 uint32_t rgbtoyuv[1<<24];
53
54typedef struct ThreadData {
55 AVFrame *in, *out;
56 const uint32_t *rgbtoyuv;
58
59#define OFFSET(x) offsetof(XBRContext, x)
60#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
61static const AVOption xbr_options[] = {
62 { "n", "set scale factor", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 3}, 2, 4, .flags = FLAGS },
63 { NULL }
64};
65
67
68static uint32_t pixel_diff(uint32_t x, uint32_t y, const uint32_t *r2y)
69{
70#define YMASK 0xff0000
71#define UMASK 0x00ff00
72#define VMASK 0x0000ff
73#define ABSDIFF(a,b) (abs((int)(a)-(int)(b)))
74
75 uint32_t yuv1 = r2y[x & 0xffffff];
76 uint32_t yuv2 = r2y[y & 0xffffff];
77
78 return (ABSDIFF(yuv1 & YMASK, yuv2 & YMASK) >> 16) +
79 (ABSDIFF(yuv1 & UMASK, yuv2 & UMASK) >> 8) +
80 ABSDIFF(yuv1 & VMASK, yuv2 & VMASK);
81}
82
83#define ALPHA_BLEND_128_W(a, b) ((((a) & LB_MASK) >> 1) + (((b) & LB_MASK) >> 1))
84#define ALPHA_BLEND_BASE(a, b, m, s) ( (RED_BLUE_MASK & (((a) & RED_BLUE_MASK) + (((((b) & RED_BLUE_MASK) - ((a) & RED_BLUE_MASK)) * (m)) >> (s)))) \
85 | (GREEN_MASK & (((a) & GREEN_MASK) + (((((b) & GREEN_MASK) - ((a) & GREEN_MASK)) * (m)) >> (s)))))
86#define ALPHA_BLEND_32_W(a, b) ALPHA_BLEND_BASE(a, b, 1, 3)
87#define ALPHA_BLEND_64_W(a, b) ALPHA_BLEND_BASE(a, b, 1, 2)
88#define ALPHA_BLEND_192_W(a, b) ALPHA_BLEND_BASE(a, b, 3, 2)
89#define ALPHA_BLEND_224_W(a, b) ALPHA_BLEND_BASE(a, b, 7, 3)
90
91#define df(A, B) pixel_diff(A, B, r2y)
92#define eq(A, B) (df(A, B) < 155)
93
94#define FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
95 N0, N1, N2, N3) do { \
96 if (PE != PH && PE != PF) { \
97 const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
98 const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
99 if (e <= i) { \
100 const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
101 if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
102 && (!eq(PF,I4) && !eq(PH,I5)) \
103 || eq(PE,PG) || eq(PE,PC))) { \
104 const unsigned ke = df(PF,PG); \
105 const unsigned ki = df(PH,PC); \
106 const int left = ke<<1 <= ki && PE != PG && PD != PG; \
107 const int up = ke >= ki<<1 && PE != PC && PB != PC; \
108 if (left && up) { \
109 E[N3] = ALPHA_BLEND_224_W(E[N3], px); \
110 E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
111 E[N1] = E[N2]; \
112 } else if (left) { \
113 E[N3] = ALPHA_BLEND_192_W(E[N3], px); \
114 E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
115 } else if (up) { \
116 E[N3] = ALPHA_BLEND_192_W(E[N3], px); \
117 E[N1] = ALPHA_BLEND_64_W( E[N1], px); \
118 } else { /* diagonal */ \
119 E[N3] = ALPHA_BLEND_128_W(E[N3], px); \
120 } \
121 } else { \
122 E[N3] = ALPHA_BLEND_128_W(E[N3], px); \
123 } \
124 } \
125 } \
126} while (0)
127
128#define FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
129 N0, N1, N2, N3, N4, N5, N6, N7, N8) do { \
130 if (PE != PH && PE != PF) { \
131 const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
132 const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
133 if (e <= i) { \
134 const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
135 if (e < i && (!eq(PF,PB) && !eq(PF,PC) || !eq(PH,PD) && !eq(PH,PG) || eq(PE,PI) \
136 && (!eq(PF,F4) && !eq(PF,I4) || !eq(PH,H5) && !eq(PH,I5)) \
137 || eq(PE,PG) || eq(PE,PC))) { \
138 const unsigned ke = df(PF,PG); \
139 const unsigned ki = df(PH,PC); \
140 const int left = ke<<1 <= ki && PE != PG && PD != PG; \
141 const int up = ke >= ki<<1 && PE != PC && PB != PC; \
142 if (left && up) { \
143 E[N7] = ALPHA_BLEND_192_W(E[N7], px); \
144 E[N6] = ALPHA_BLEND_64_W( E[N6], px); \
145 E[N5] = E[N7]; \
146 E[N2] = E[N6]; \
147 E[N8] = px; \
148 } else if (left) { \
149 E[N7] = ALPHA_BLEND_192_W(E[N7], px); \
150 E[N5] = ALPHA_BLEND_64_W( E[N5], px); \
151 E[N6] = ALPHA_BLEND_64_W( E[N6], px); \
152 E[N8] = px; \
153 } else if (up) { \
154 E[N5] = ALPHA_BLEND_192_W(E[N5], px); \
155 E[N7] = ALPHA_BLEND_64_W( E[N7], px); \
156 E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
157 E[N8] = px; \
158 } else { /* diagonal */ \
159 E[N8] = ALPHA_BLEND_224_W(E[N8], px); \
160 E[N5] = ALPHA_BLEND_32_W( E[N5], px); \
161 E[N7] = ALPHA_BLEND_32_W( E[N7], px); \
162 } \
163 } else { \
164 E[N8] = ALPHA_BLEND_128_W(E[N8], px); \
165 } \
166 } \
167 } \
168} while (0)
169
170#define FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
171 N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0) do { \
172 if (PE != PH && PE != PF) { \
173 const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
174 const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
175 if (e <= i) { \
176 const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
177 if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
178 && (!eq(PF,I4) && !eq(PH,I5)) \
179 || eq(PE,PG) || eq(PE,PC))) { \
180 const unsigned ke = df(PF,PG); \
181 const unsigned ki = df(PH,PC); \
182 const int left = ke<<1 <= ki && PE != PG && PD != PG; \
183 const int up = ke >= ki<<1 && PE != PC && PB != PC; \
184 if (left && up) { \
185 E[N13] = ALPHA_BLEND_192_W(E[N13], px); \
186 E[N12] = ALPHA_BLEND_64_W( E[N12], px); \
187 E[N15] = E[N14] = E[N11] = px; \
188 E[N10] = E[N3] = E[N12]; \
189 E[N7] = E[N13]; \
190 } else if (left) { \
191 E[N11] = ALPHA_BLEND_192_W(E[N11], px); \
192 E[N13] = ALPHA_BLEND_192_W(E[N13], px); \
193 E[N10] = ALPHA_BLEND_64_W( E[N10], px); \
194 E[N12] = ALPHA_BLEND_64_W( E[N12], px); \
195 E[N14] = px; \
196 E[N15] = px; \
197 } else if (up) { \
198 E[N14] = ALPHA_BLEND_192_W(E[N14], px); \
199 E[N7 ] = ALPHA_BLEND_192_W(E[N7 ], px); \
200 E[N10] = ALPHA_BLEND_64_W( E[N10], px); \
201 E[N3 ] = ALPHA_BLEND_64_W( E[N3 ], px); \
202 E[N11] = px; \
203 E[N15] = px; \
204 } else { /* diagonal */ \
205 E[N11] = ALPHA_BLEND_128_W(E[N11], px); \
206 E[N14] = ALPHA_BLEND_128_W(E[N14], px); \
207 E[N15] = px; \
208 } \
209 } else { \
210 E[N15] = ALPHA_BLEND_128_W(E[N15], px); \
211 } \
212 } \
213 } \
214} while (0)
215
216static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
217{
218 int x, y;
219 const AVFrame *input = td->in;
220 AVFrame *output = td->out;
221 const uint32_t *r2y = td->rgbtoyuv;
222 const int slice_start = ff_slice_pos(input->height, jobnr, nb_jobs);
223 const int slice_end = ff_slice_pos(input->height, jobnr + 1, nb_jobs);
224 const int nl = output->linesize[0] >> 2;
225 const int nl1 = nl + nl;
226 const int nl2 = nl1 + nl;
227
228 for (y = slice_start; y < slice_end; y++) {
229
230 uint32_t *E = (uint32_t *)(output->data[0] + y * output->linesize[0] * n);
231 const uint32_t *sa2 = (uint32_t *)(input->data[0] + y * input->linesize[0] - 8); /* center */
232 const uint32_t *sa1 = sa2 - (input->linesize[0]>>2); /* up x1 */
233 const uint32_t *sa0 = sa1 - (input->linesize[0]>>2); /* up x2 */
234 const uint32_t *sa3 = sa2 + (input->linesize[0]>>2); /* down x1 */
235 const uint32_t *sa4 = sa3 + (input->linesize[0]>>2); /* down x2 */
236
237 if (y <= 1) {
238 sa0 = sa1;
239 if (y == 0) {
240 sa0 = sa1 = sa2;
241 }
242 }
243
244 if (y >= input->height - 2) {
245 sa4 = sa3;
246 if (y == input->height - 1) {
247 sa4 = sa3 = sa2;
248 }
249 }
250
251 for (x = 0; x < input->width; x++) {
252 const uint32_t B1 = sa0[2];
253 const uint32_t PB = sa1[2];
254 const uint32_t PE = sa2[2];
255 const uint32_t PH = sa3[2];
256 const uint32_t H5 = sa4[2];
257
258 const int pprev = 2 - (x > 0);
259 const uint32_t A1 = sa0[pprev];
260 const uint32_t PA = sa1[pprev];
261 const uint32_t PD = sa2[pprev];
262 const uint32_t PG = sa3[pprev];
263 const uint32_t G5 = sa4[pprev];
264
265 const int pprev2 = pprev - (x > 1);
266 const uint32_t A0 = sa1[pprev2];
267 const uint32_t D0 = sa2[pprev2];
268 const uint32_t G0 = sa3[pprev2];
269
270 const int pnext = 3 - (x == input->width - 1);
271 const uint32_t C1 = sa0[pnext];
272 const uint32_t PC = sa1[pnext];
273 const uint32_t PF = sa2[pnext];
274 const uint32_t PI = sa3[pnext];
275 const uint32_t I5 = sa4[pnext];
276
277 const int pnext2 = pnext + 1 - (x >= input->width - 2);
278 const uint32_t C4 = sa1[pnext2];
279 const uint32_t F4 = sa2[pnext2];
280 const uint32_t I4 = sa3[pnext2];
281
282 if (n == 2) {
283 E[0] = E[1] = // 0, 1
284 E[nl] = E[nl + 1] = PE; // 2, 3
285
286 FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, nl, nl+1);
287 FILT2(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, nl, 0, nl+1, 1);
288 FILT2(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, nl+1, nl, 1, 0);
289 FILT2(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 1, nl+1, 0, nl);
290 } else if (n == 3) {
291 E[0] = E[1] = E[2] = // 0, 1, 2
292 E[nl] = E[nl+1] = E[nl+2] = // 3, 4, 5
293 E[nl1] = E[nl1+1] = E[nl1+2] = PE; // 6, 7, 8
294
295 FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, 2, nl, nl+1, nl+2, nl1, nl1+1, nl1+2);
296 FILT3(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, nl1, nl, 0, nl1+1, nl+1, 1, nl1+2, nl+2, 2);
297 FILT3(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, nl1+2, nl1+1, nl1, nl+2, nl+1, nl, 2, 1, 0);
298 FILT3(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 2, nl+2, nl1+2, 1, nl+1, nl1+1, 0, nl, nl1);
299 } else if (n == 4) {
300 E[0] = E[1] = E[2] = E[3] = // 0, 1, 2, 3
301 E[nl] = E[nl+1] = E[nl+2] = E[nl+3] = // 4, 5, 6, 7
302 E[nl1] = E[nl1+1] = E[nl1+2] = E[nl1+3] = // 8, 9, 10, 11
303 E[nl2] = E[nl2+1] = E[nl2+2] = E[nl2+3] = PE; // 12, 13, 14, 15
304
305 FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, nl2+3, nl2+2, nl1+3, 3, nl+3, nl1+2, nl2+1, nl2, nl1+1, nl+2, 2, 1, nl+1, nl1, nl, 0);
306 FILT4(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, 3, nl+3, 2, 0, 1, nl+2, nl1+3, nl2+3, nl1+2, nl+1, nl, nl1, nl1+1, nl2+2, nl2+1, nl2);
307 FILT4(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, 0, 1, nl, nl2, nl1, nl+1, 2, 3, nl+2, nl1+1, nl2+1, nl2+2, nl1+2, nl+3, nl1+3, nl2+3);
308 FILT4(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, nl2, nl1, nl2+1, nl2+3, nl2+2, nl1+1, nl, 0, nl+1, nl1+2, nl1+3, nl+3, nl+2, 1, 2, 3);
309 }
310
311 sa0 += 1;
312 sa1 += 1;
313 sa2 += 1;
314 sa3 += 1;
315 sa4 += 1;
316
317 E += n;
318 }
319 }
320}
321
322#define XBR_FUNC(size) \
323static int xbr##size##x(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
324{ \
325 xbr_filter(arg, jobnr, nb_jobs, size); \
326 return 0; \
327}
328
329XBR_FUNC(2)
330XBR_FUNC(3)
331XBR_FUNC(4)
332
333
334static int config_output(AVFilterLink *outlink)
335{
336 AVFilterContext *ctx = outlink->src;
337 XBRContext *s = ctx->priv;
338 AVFilterLink *inlink = ctx->inputs[0];
339
340 outlink->w = inlink->w * s->n;
341 outlink->h = inlink->h * s->n;
342 return 0;
343}
344
345static int filter_frame(AVFilterLink *inlink, AVFrame *in)
346{
347 AVFilterContext *ctx = inlink->dst;
348 AVFilterLink *outlink = ctx->outputs[0];
349 XBRContext *s = ctx->priv;
350 ThreadData td;
351
352 AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
353 if (!out) {
354 av_frame_free(&in);
355 return AVERROR(ENOMEM);
356 }
357
359
360 td.in = in;
361 td.out = out;
362 td.rgbtoyuv = s->rgbtoyuv;
363 ff_filter_execute(ctx, s->func, &td, NULL,
365
366 out->width = outlink->w;
367 out->height = outlink->h;
368
369 av_frame_free(&in);
370 return ff_filter_frame(outlink, out);
371}
372
374{
375 XBRContext *s = ctx->priv;
376 static const xbrfunc_t xbrfuncs[] = {xbr2x, xbr3x, xbr4x};
377
378 uint32_t c;
379 int bg, rg, g;
380
381 for (bg = -255; bg < 256; bg++) {
382 for (rg = -255; rg < 256; rg++) {
383 const uint32_t u = (uint32_t)((-169*rg + 500*bg)/1000) + 128;
384 const uint32_t v = (uint32_t)(( 500*rg - 81*bg)/1000) + 128;
385 int startg = FFMAX3(-bg, -rg, 0);
386 int endg = FFMIN3(255-bg, 255-rg, 255);
387 uint32_t y = (uint32_t)(( 299*rg + 1000*startg + 114*bg)/1000);
388 c = bg + rg * (1 << 16) + 0x010101 * startg;
389 for (g = startg; g <= endg; g++) {
390 s->rgbtoyuv[c] = ((y++) << 16) + (u << 8) + v;
391 c+= 0x010101;
392 }
393 }
394 }
395
396 s->func = xbrfuncs[s->n - 2];
397 return 0;
398}
399
400static const AVFilterPad xbr_inputs[] = {
401 {
402 .name = "default",
403 .type = AVMEDIA_TYPE_VIDEO,
404 .filter_frame = filter_frame,
405 },
406};
407
408static const AVFilterPad xbr_outputs[] = {
409 {
410 .name = "default",
411 .type = AVMEDIA_TYPE_VIDEO,
412 .config_props = config_output,
413 },
414};
415
417 .p.name = "xbr",
418 .p.description = NULL_IF_CONFIG_SMALL("Scale the input using xBR algorithm."),
419 .p.priv_class = &xbr_class,
424 .priv_size = sizeof(XBRContext),
425 .init = init,
426};
const FFFilter ff_vf_xbr
Definition vf_xbr.c:416
static FILE * out
static AVFormatContext * ctx
#define E
Definition avdct.c:34
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition avfilter.c:1696
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition avfilter.c:846
#define A1
Definition binkdsp.c:30
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:598
#define NULL
Definition coverity.c:32
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define B1
Definition faandct.c:42
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition avfilter.h:166
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define PD(a, b)
Pack two delta values (a,b) into one 16-bit word according with endianness of the host machine.
Definition indeo3data.h:243
static int config_output(AVBitStreamFilterLink *outlink)
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
const char * arg
Definition jacosubdec.c:65
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
Definition filters.h:763
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition filters.h:254
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define av_always_inline
Definition attributes.h:72
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define FFMAX3(a, b, c)
Definition macros.h:48
#define FFMIN(a, b)
Definition macros.h:49
#define FFMIN3(a, b, c)
Definition macros.h:50
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
Definition mpeg12dec.c:1697
#define C4
#define C1
AVOptions.
#define AV_PIX_FMT_0RGB32
Definition pixfmt.h:521
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int width
Definition frame.h:544
int height
Definition frame.h:544
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
AVOption.
Definition opt.h:428
Used for passing data between threads.
Definition dsddec.c:71
const uint32_t * rgbtoyuv
Definition vf_hqx.c:47
AVFrame * out
uint32_t rgbtoyuv[1<< 24]
Definition vf_xbr.c:51
xbrfunc_t func
Definition vf_xbr.c:50
int n
Definition vf_xbr.c:49
#define PF(suf)
const char * g
Definition vf_curves.c:128
#define YMASK
#define VMASK
#define UMASK
static uint32_t pixel_diff(uint32_t x, uint32_t y, const uint32_t *r2y)
Definition vf_xbr.c:68
#define ABSDIFF(a, b)
#define FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3, N4, N5, N6, N7, N8)
Definition vf_xbr.c:128
#define XBR_FUNC(size)
Definition vf_xbr.c:322
static const AVOption xbr_options[]
Definition vf_xbr.c:61
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition vf_xbr.c:345
#define FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0)
Definition vf_xbr.c:170
static const AVFilterPad xbr_outputs[]
Definition vf_xbr.c:408
static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
Definition vf_xbr.c:216
static const AVFilterPad xbr_inputs[]
Definition vf_xbr.c:400
#define OFFSET(x)
Definition vf_xbr.c:59
int(* xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition vf_xbr.c:45
#define FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3)
Definition vf_xbr.c:94
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition video.c:89
static double c[64]
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition dec.c:844
@ A0
Definition mvs.c:528