FFmpeg
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 #include "internal.h"
34 
35 #define LB_MASK 0x00FEFEFE
36 #define RED_BLUE_MASK 0x00FF00FF
37 #define GREEN_MASK 0x0000FF00
38 
39 #ifdef PI
40 #undef PI
41 #endif
42 
43 typedef int (*xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
44 
45 typedef struct XBRContext {
46  const AVClass *class;
47  int n;
49  uint32_t rgbtoyuv[1<<24];
50 } XBRContext;
51 
52 typedef struct ThreadData {
53  AVFrame *in, *out;
54  const uint32_t *rgbtoyuv;
55 } ThreadData;
56 
57 #define OFFSET(x) offsetof(XBRContext, x)
58 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
59 static const AVOption xbr_options[] = {
60  { "n", "set scale factor", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 3}, 2, 4, .flags = FLAGS },
61  { NULL }
62 };
63 
65 
66 static uint32_t pixel_diff(uint32_t x, uint32_t y, const uint32_t *r2y)
67 {
68 #define YMASK 0xff0000
69 #define UMASK 0x00ff00
70 #define VMASK 0x0000ff
71 #define ABSDIFF(a,b) (abs((int)(a)-(int)(b)))
72 
73  uint32_t yuv1 = r2y[x & 0xffffff];
74  uint32_t yuv2 = r2y[y & 0xffffff];
75 
76  return (ABSDIFF(yuv1 & YMASK, yuv2 & YMASK) >> 16) +
77  (ABSDIFF(yuv1 & UMASK, yuv2 & UMASK) >> 8) +
78  ABSDIFF(yuv1 & VMASK, yuv2 & VMASK);
79 }
80 
81 #define ALPHA_BLEND_128_W(a, b) ((((a) & LB_MASK) >> 1) + (((b) & LB_MASK) >> 1))
82 #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)))) \
83  | (GREEN_MASK & (((a) & GREEN_MASK) + (((((b) & GREEN_MASK) - ((a) & GREEN_MASK)) * (m)) >> (s)))))
84 #define ALPHA_BLEND_32_W(a, b) ALPHA_BLEND_BASE(a, b, 1, 3)
85 #define ALPHA_BLEND_64_W(a, b) ALPHA_BLEND_BASE(a, b, 1, 2)
86 #define ALPHA_BLEND_192_W(a, b) ALPHA_BLEND_BASE(a, b, 3, 2)
87 #define ALPHA_BLEND_224_W(a, b) ALPHA_BLEND_BASE(a, b, 7, 3)
88 
89 #define df(A, B) pixel_diff(A, B, r2y)
90 #define eq(A, B) (df(A, B) < 155)
91 
92 #define FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
93  N0, N1, N2, N3) do { \
94  if (PE != PH && PE != PF) { \
95  const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
96  const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
97  if (e <= i) { \
98  const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
99  if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
100  && (!eq(PF,I4) && !eq(PH,I5)) \
101  || eq(PE,PG) || eq(PE,PC))) { \
102  const unsigned ke = df(PF,PG); \
103  const unsigned ki = df(PH,PC); \
104  const int left = ke<<1 <= ki && PE != PG && PD != PG; \
105  const int up = ke >= ki<<1 && PE != PC && PB != PC; \
106  if (left && up) { \
107  E[N3] = ALPHA_BLEND_224_W(E[N3], px); \
108  E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
109  E[N1] = E[N2]; \
110  } else if (left) { \
111  E[N3] = ALPHA_BLEND_192_W(E[N3], px); \
112  E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
113  } else if (up) { \
114  E[N3] = ALPHA_BLEND_192_W(E[N3], px); \
115  E[N1] = ALPHA_BLEND_64_W( E[N1], px); \
116  } else { /* diagonal */ \
117  E[N3] = ALPHA_BLEND_128_W(E[N3], px); \
118  } \
119  } else { \
120  E[N3] = ALPHA_BLEND_128_W(E[N3], px); \
121  } \
122  } \
123  } \
124 } while (0)
125 
126 #define FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
127  N0, N1, N2, N3, N4, N5, N6, N7, N8) do { \
128  if (PE != PH && PE != PF) { \
129  const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
130  const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
131  if (e <= i) { \
132  const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
133  if (e < i && (!eq(PF,PB) && !eq(PF,PC) || !eq(PH,PD) && !eq(PH,PG) || eq(PE,PI) \
134  && (!eq(PF,F4) && !eq(PF,I4) || !eq(PH,H5) && !eq(PH,I5)) \
135  || eq(PE,PG) || eq(PE,PC))) { \
136  const unsigned ke = df(PF,PG); \
137  const unsigned ki = df(PH,PC); \
138  const int left = ke<<1 <= ki && PE != PG && PD != PG; \
139  const int up = ke >= ki<<1 && PE != PC && PB != PC; \
140  if (left && up) { \
141  E[N7] = ALPHA_BLEND_192_W(E[N7], px); \
142  E[N6] = ALPHA_BLEND_64_W( E[N6], px); \
143  E[N5] = E[N7]; \
144  E[N2] = E[N6]; \
145  E[N8] = px; \
146  } else if (left) { \
147  E[N7] = ALPHA_BLEND_192_W(E[N7], px); \
148  E[N5] = ALPHA_BLEND_64_W( E[N5], px); \
149  E[N6] = ALPHA_BLEND_64_W( E[N6], px); \
150  E[N8] = px; \
151  } else if (up) { \
152  E[N5] = ALPHA_BLEND_192_W(E[N5], px); \
153  E[N7] = ALPHA_BLEND_64_W( E[N7], px); \
154  E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
155  E[N8] = px; \
156  } else { /* diagonal */ \
157  E[N8] = ALPHA_BLEND_224_W(E[N8], px); \
158  E[N5] = ALPHA_BLEND_32_W( E[N5], px); \
159  E[N7] = ALPHA_BLEND_32_W( E[N7], px); \
160  } \
161  } else { \
162  E[N8] = ALPHA_BLEND_128_W(E[N8], px); \
163  } \
164  } \
165  } \
166 } while (0)
167 
168 #define FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
169  N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0) do { \
170  if (PE != PH && PE != PF) { \
171  const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
172  const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
173  if (e <= i) { \
174  const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
175  if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
176  && (!eq(PF,I4) && !eq(PH,I5)) \
177  || eq(PE,PG) || eq(PE,PC))) { \
178  const unsigned ke = df(PF,PG); \
179  const unsigned ki = df(PH,PC); \
180  const int left = ke<<1 <= ki && PE != PG && PD != PG; \
181  const int up = ke >= ki<<1 && PE != PC && PB != PC; \
182  if (left && up) { \
183  E[N13] = ALPHA_BLEND_192_W(E[N13], px); \
184  E[N12] = ALPHA_BLEND_64_W( E[N12], px); \
185  E[N15] = E[N14] = E[N11] = px; \
186  E[N10] = E[N3] = E[N12]; \
187  E[N7] = E[N13]; \
188  } else if (left) { \
189  E[N11] = ALPHA_BLEND_192_W(E[N11], px); \
190  E[N13] = ALPHA_BLEND_192_W(E[N13], px); \
191  E[N10] = ALPHA_BLEND_64_W( E[N10], px); \
192  E[N12] = ALPHA_BLEND_64_W( E[N12], px); \
193  E[N14] = px; \
194  E[N15] = px; \
195  } else if (up) { \
196  E[N14] = ALPHA_BLEND_192_W(E[N14], px); \
197  E[N7 ] = ALPHA_BLEND_192_W(E[N7 ], px); \
198  E[N10] = ALPHA_BLEND_64_W( E[N10], px); \
199  E[N3 ] = ALPHA_BLEND_64_W( E[N3 ], px); \
200  E[N11] = px; \
201  E[N15] = px; \
202  } else { /* diagonal */ \
203  E[N11] = ALPHA_BLEND_128_W(E[N11], px); \
204  E[N14] = ALPHA_BLEND_128_W(E[N14], px); \
205  E[N15] = px; \
206  } \
207  } else { \
208  E[N15] = ALPHA_BLEND_128_W(E[N15], px); \
209  } \
210  } \
211  } \
212 } while (0)
213 
214 static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
215 {
216  int x, y;
217  const AVFrame *input = td->in;
218  AVFrame *output = td->out;
219  const uint32_t *r2y = td->rgbtoyuv;
220  const int slice_start = (input->height * jobnr ) / nb_jobs;
221  const int slice_end = (input->height * (jobnr+1)) / nb_jobs;
222  const int nl = output->linesize[0] >> 2;
223  const int nl1 = nl + nl;
224  const int nl2 = nl1 + nl;
225 
226  for (y = slice_start; y < slice_end; y++) {
227 
228  uint32_t *E = (uint32_t *)(output->data[0] + y * output->linesize[0] * n);
229  const uint32_t *sa2 = (uint32_t *)(input->data[0] + y * input->linesize[0] - 8); /* center */
230  const uint32_t *sa1 = sa2 - (input->linesize[0]>>2); /* up x1 */
231  const uint32_t *sa0 = sa1 - (input->linesize[0]>>2); /* up x2 */
232  const uint32_t *sa3 = sa2 + (input->linesize[0]>>2); /* down x1 */
233  const uint32_t *sa4 = sa3 + (input->linesize[0]>>2); /* down x2 */
234 
235  if (y <= 1) {
236  sa0 = sa1;
237  if (y == 0) {
238  sa0 = sa1 = sa2;
239  }
240  }
241 
242  if (y >= input->height - 2) {
243  sa4 = sa3;
244  if (y == input->height - 1) {
245  sa4 = sa3 = sa2;
246  }
247  }
248 
249  for (x = 0; x < input->width; x++) {
250  const uint32_t B1 = sa0[2];
251  const uint32_t PB = sa1[2];
252  const uint32_t PE = sa2[2];
253  const uint32_t PH = sa3[2];
254  const uint32_t H5 = sa4[2];
255 
256  const int pprev = 2 - (x > 0);
257  const uint32_t A1 = sa0[pprev];
258  const uint32_t PA = sa1[pprev];
259  const uint32_t PD = sa2[pprev];
260  const uint32_t PG = sa3[pprev];
261  const uint32_t G5 = sa4[pprev];
262 
263  const int pprev2 = pprev - (x > 1);
264  const uint32_t A0 = sa1[pprev2];
265  const uint32_t D0 = sa2[pprev2];
266  const uint32_t G0 = sa3[pprev2];
267 
268  const int pnext = 3 - (x == input->width - 1);
269  const uint32_t C1 = sa0[pnext];
270  const uint32_t PC = sa1[pnext];
271  const uint32_t PF = sa2[pnext];
272  const uint32_t PI = sa3[pnext];
273  const uint32_t I5 = sa4[pnext];
274 
275  const int pnext2 = pnext + 1 - (x >= input->width - 2);
276  const uint32_t C4 = sa1[pnext2];
277  const uint32_t F4 = sa2[pnext2];
278  const uint32_t I4 = sa3[pnext2];
279 
280  if (n == 2) {
281  E[0] = E[1] = // 0, 1
282  E[nl] = E[nl + 1] = PE; // 2, 3
283 
284  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);
285  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);
286  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);
287  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);
288  } else if (n == 3) {
289  E[0] = E[1] = E[2] = // 0, 1, 2
290  E[nl] = E[nl+1] = E[nl+2] = // 3, 4, 5
291  E[nl1] = E[nl1+1] = E[nl1+2] = PE; // 6, 7, 8
292 
293  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);
294  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);
295  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);
296  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);
297  } else if (n == 4) {
298  E[0] = E[1] = E[2] = E[3] = // 0, 1, 2, 3
299  E[nl] = E[nl+1] = E[nl+2] = E[nl+3] = // 4, 5, 6, 7
300  E[nl1] = E[nl1+1] = E[nl1+2] = E[nl1+3] = // 8, 9, 10, 11
301  E[nl2] = E[nl2+1] = E[nl2+2] = E[nl2+3] = PE; // 12, 13, 14, 15
302 
303  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);
304  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);
305  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);
306  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);
307  }
308 
309  sa0 += 1;
310  sa1 += 1;
311  sa2 += 1;
312  sa3 += 1;
313  sa4 += 1;
314 
315  E += n;
316  }
317  }
318 }
319 
320 #define XBR_FUNC(size) \
321 static int xbr##size##x(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
322 { \
323  xbr_filter(arg, jobnr, nb_jobs, size); \
324  return 0; \
325 }
326 
327 XBR_FUNC(2)
328 XBR_FUNC(3)
329 XBR_FUNC(4)
330 
331 
332 static int config_output(AVFilterLink *outlink)
333 {
334  AVFilterContext *ctx = outlink->src;
335  XBRContext *s = ctx->priv;
336  AVFilterLink *inlink = ctx->inputs[0];
337 
338  outlink->w = inlink->w * s->n;
339  outlink->h = inlink->h * s->n;
340  return 0;
341 }
342 
344 {
345  AVFilterContext *ctx = inlink->dst;
346  AVFilterLink *outlink = ctx->outputs[0];
347  XBRContext *s = ctx->priv;
348  ThreadData td;
349 
350  AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
351  if (!out) {
352  av_frame_free(&in);
353  return AVERROR(ENOMEM);
354  }
355 
357 
358  td.in = in;
359  td.out = out;
360  td.rgbtoyuv = s->rgbtoyuv;
361  ff_filter_execute(ctx, s->func, &td, NULL,
363 
364  out->width = outlink->w;
365  out->height = outlink->h;
366 
367  av_frame_free(&in);
368  return ff_filter_frame(outlink, out);
369 }
370 
372 {
373  XBRContext *s = ctx->priv;
374  static const xbrfunc_t xbrfuncs[] = {xbr2x, xbr3x, xbr4x};
375 
376  uint32_t c;
377  int bg, rg, g;
378 
379  for (bg = -255; bg < 256; bg++) {
380  for (rg = -255; rg < 256; rg++) {
381  const uint32_t u = (uint32_t)((-169*rg + 500*bg)/1000) + 128;
382  const uint32_t v = (uint32_t)(( 500*rg - 81*bg)/1000) + 128;
383  int startg = FFMAX3(-bg, -rg, 0);
384  int endg = FFMIN3(255-bg, 255-rg, 255);
385  uint32_t y = (uint32_t)(( 299*rg + 1000*startg + 114*bg)/1000);
386  c = bg + rg * (1 << 16) + 0x010101 * startg;
387  for (g = startg; g <= endg; g++) {
388  s->rgbtoyuv[c] = ((y++) << 16) + (u << 8) + v;
389  c+= 0x010101;
390  }
391  }
392  }
393 
394  s->func = xbrfuncs[s->n - 2];
395  return 0;
396 }
397 
398 static const AVFilterPad xbr_inputs[] = {
399  {
400  .name = "default",
401  .type = AVMEDIA_TYPE_VIDEO,
402  .filter_frame = filter_frame,
403  },
404 };
405 
406 static const AVFilterPad xbr_outputs[] = {
407  {
408  .name = "default",
409  .type = AVMEDIA_TYPE_VIDEO,
410  .config_props = config_output,
411  },
412 };
413 
415  .name = "xbr",
416  .description = NULL_IF_CONFIG_SMALL("Scale the input using xBR algorithm."),
420  .priv_size = sizeof(XBRContext),
421  .priv_class = &xbr_class,
422  .init = init,
424 };
ff_vf_xbr
const AVFilter ff_vf_xbr
Definition: vf_xbr.c:414
VMASK
#define VMASK
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:101
td
#define td
Definition: regdef.h:70
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
B1
#define B1
Definition: faandct.c:41
out
FILE * out
Definition: movenc.c:54
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:262
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:969
xbr_outputs
static const AVFilterPad xbr_outputs[]
Definition: vf_xbr.c:406
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:99
test::height
int height
Definition: vc1dsp.c:39
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
pixdesc.h
C4
#define C4
Definition: mpegaudiodec_template.c:318
AVOption
AVOption.
Definition: opt.h:251
xbr_inputs
static const AVFilterPad xbr_inputs[]
Definition: vf_xbr.c:398
PD
#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:290
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:165
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:473
ThreadData::in
AVFrame * in
Definition: af_adecorrelate.c:154
ABSDIFF
#define ABSDIFF(a, b)
xbr_options
static const AVOption xbr_options[]
Definition: vf_xbr.c:59
C1
#define C1
Definition: mpegaudiodsp_template.c:238
XBRContext::n
int n
Definition: vf_xbr.c:47
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
xbrfunc_t
int(* xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_xbr.c:43
XBRContext::rgbtoyuv
uint32_t rgbtoyuv[1<< 24]
Definition: vf_xbr.c:49
XBRContext::func
xbrfunc_t func
Definition: vf_xbr.c:48
av_cold
#define av_cold
Definition: attributes.h:90
YMASK
#define YMASK
s
#define s(width, name)
Definition: cbs_vp9.c:256
g
const char * g
Definition: vf_curves.c:127
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2006
FLAGS
#define FLAGS
Definition: vf_xbr.c:58
ctx
AVFormatContext * ctx
Definition: movenc.c:48
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:194
E
#define E
Definition: avdct.c:32
arg
const char * arg
Definition: jacosubdec.c:67
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:594
PF
#define PF(suf)
xbr_filter
static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
Definition: vf_xbr.c:214
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
XBRContext
Definition: vf_xbr.c:45
test::width
int width
Definition: vc1dsp.c:38
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:115
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_xbr.c:332
ThreadData::rgbtoyuv
const uint32_t * rgbtoyuv
Definition: vf_hqx.c:46
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
internal.h
FILTER_SINGLE_PIXFMT
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition: internal.h:184
UMASK
#define UMASK
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:777
ThreadData
Used for passing data between threads.
Definition: dsddec.c:69
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
XBR_FUNC
#define XBR_FUNC(size)
Definition: vf_xbr.c:320
AVFilter
Filter definition.
Definition: avfilter.h:161
AV_PIX_FMT_0RGB32
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:436
FILT4
#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:168
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_xbr.c:343
AVFilterContext
An instance of a filter.
Definition: avfilter.h:392
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
pixel_diff
static uint32_t pixel_diff(uint32_t x, uint32_t y, const uint32_t *r2y)
Definition: vf_xbr.c:66
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_xbr.c:371
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:195
FFMAX3
#define FFMAX3(a, b, c)
Definition: macros.h:48
A1
#define A1
Definition: binkdsp.c:31
OFFSET
#define OFFSET(x)
Definition: vf_xbr.c:57
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(xbr)
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:146
int
int
Definition: ffmpeg_filter.c:156
FILT2
#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:92
FILT3
#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:126