FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 http://www.libretro.com/forums/viewtopic.php?f=6&t=134
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/avassert.h"
33 #include "libavutil/pixdesc.h"
34 #include "internal.h"
35 
36 #define LB_MASK 0x00FEFEFE
37 #define RED_BLUE_MASK 0x00FF00FF
38 #define GREEN_MASK 0x0000FF00
39 
40 typedef int (*xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
41 
42 typedef struct {
43  const AVClass *class;
44  int n;
46  uint32_t rgbtoyuv[1<<24];
47 } XBRContext;
48 
49 typedef struct ThreadData {
50  AVFrame *in, *out;
51  const uint32_t *rgbtoyuv;
52 } ThreadData;
53 
54 #define OFFSET(x) offsetof(XBRContext, x)
55 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
56 static const AVOption xbr_options[] = {
57  { "n", "set scale factor", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 3}, 2, 4, .flags = FLAGS },
58  { NULL }
59 };
60 
62 
63 static uint32_t pixel_diff(uint32_t x, uint32_t y, const uint32_t *r2y)
64 {
65 #define YMASK 0xff0000
66 #define UMASK 0x00ff00
67 #define VMASK 0x0000ff
68 #define ABSDIFF(a,b) (abs((int)(a)-(int)(b)))
69 
70  uint32_t yuv1 = r2y[x & 0xffffff];
71  uint32_t yuv2 = r2y[y & 0xffffff];
72 
73  return (ABSDIFF(yuv1 & YMASK, yuv2 & YMASK) >> 16) +
74  (ABSDIFF(yuv1 & UMASK, yuv2 & UMASK) >> 8) +
75  ABSDIFF(yuv1 & VMASK, yuv2 & VMASK);
76 }
77 
78 #define ALPHA_BLEND_128_W(a, b) ((((a) & LB_MASK) >> 1) + (((b) & LB_MASK) >> 1))
79 #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)))) \
80  | (GREEN_MASK & (((a) & GREEN_MASK) + (((((b) & GREEN_MASK) - ((a) & GREEN_MASK)) * (m)) >> (s)))))
81 #define ALPHA_BLEND_32_W(a, b) ALPHA_BLEND_BASE(a, b, 1, 3)
82 #define ALPHA_BLEND_64_W(a, b) ALPHA_BLEND_BASE(a, b, 1, 2)
83 #define ALPHA_BLEND_192_W(a, b) ALPHA_BLEND_BASE(a, b, 3, 2)
84 #define ALPHA_BLEND_224_W(a, b) ALPHA_BLEND_BASE(a, b, 7, 3)
85 
86 #define df(A, B) pixel_diff(A, B, r2y)
87 #define eq(A, B) (df(A, B) < 155)
88 
89 #define FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
90  N0, N1, N2, N3) do { \
91  if (PE != PH && PE != PF) { \
92  const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
93  const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
94  if (e <= i) { \
95  const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
96  if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
97  && (!eq(PF,I4) && !eq(PH,I5)) \
98  || eq(PE,PG) || eq(PE,PC))) { \
99  const unsigned ke = df(PF,PG); \
100  const unsigned ki = df(PH,PC); \
101  const int left = ke<<1 <= ki && PE != PG && PD != PG; \
102  const int up = ke >= ki<<1 && PE != PC && PB != PC; \
103  if (left && up) { \
104  E[N3] = ALPHA_BLEND_224_W(E[N3], px); \
105  E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
106  E[N1] = E[N2]; \
107  } else if (left) { \
108  E[N3] = ALPHA_BLEND_192_W(E[N3], px); \
109  E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
110  } else if (up) { \
111  E[N3] = ALPHA_BLEND_192_W(E[N3], px); \
112  E[N1] = ALPHA_BLEND_64_W( E[N1], px); \
113  } else { /* diagonal */ \
114  E[N3] = ALPHA_BLEND_128_W(E[N3], px); \
115  } \
116  } else { \
117  E[N3] = ALPHA_BLEND_128_W(E[N3], px); \
118  } \
119  } \
120  } \
121 } while (0)
122 
123 #define FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
124  N0, N1, N2, N3, N4, N5, N6, N7, N8) do { \
125  if (PE != PH && PE != PF) { \
126  const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
127  const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
128  if (e <= i) { \
129  const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
130  if (e < i && (!eq(PF,PB) && !eq(PF,PC) || !eq(PH,PD) && !eq(PH,PG) || eq(PE,PI) \
131  && (!eq(PF,F4) && !eq(PF,I4) || !eq(PH,H5) && !eq(PH,I5)) \
132  || eq(PE,PG) || eq(PE,PC))) { \
133  const unsigned ke = df(PF,PG); \
134  const unsigned ki = df(PH,PC); \
135  const int left = ke<<1 <= ki && PE != PG && PD != PG; \
136  const int up = ke >= ki<<1 && PE != PC && PB != PC; \
137  if (left && up) { \
138  E[N7] = ALPHA_BLEND_192_W(E[N7], px); \
139  E[N6] = ALPHA_BLEND_64_W( E[N6], px); \
140  E[N5] = E[N7]; \
141  E[N2] = E[N6]; \
142  E[N8] = px; \
143  } else if (left) { \
144  E[N7] = ALPHA_BLEND_192_W(E[N7], px); \
145  E[N5] = ALPHA_BLEND_64_W( E[N5], px); \
146  E[N6] = ALPHA_BLEND_64_W( E[N6], px); \
147  E[N8] = px; \
148  } else if (up) { \
149  E[N5] = ALPHA_BLEND_192_W(E[N5], px); \
150  E[N7] = ALPHA_BLEND_64_W( E[N7], px); \
151  E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
152  E[N8] = px; \
153  } else { /* diagonal */ \
154  E[N8] = ALPHA_BLEND_224_W(E[N8], px); \
155  E[N5] = ALPHA_BLEND_32_W( E[N5], px); \
156  E[N7] = ALPHA_BLEND_32_W( E[N7], px); \
157  } \
158  } else { \
159  E[N8] = ALPHA_BLEND_128_W(E[N8], px); \
160  } \
161  } \
162  } \
163 } while (0)
164 
165 #define FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
166  N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0) do { \
167  if (PE != PH && PE != PF) { \
168  const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
169  const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
170  if (e <= i) { \
171  const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
172  if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
173  && (!eq(PF,I4) && !eq(PH,I5)) \
174  || eq(PE,PG) || eq(PE,PC))) { \
175  const unsigned ke = df(PF,PG); \
176  const unsigned ki = df(PH,PC); \
177  const int left = ke<<1 <= ki && PE != PG && PD != PG; \
178  const int up = ke >= ki<<1 && PE != PC && PB != PC; \
179  if (left && up) { \
180  E[N13] = ALPHA_BLEND_192_W(E[N13], px); \
181  E[N12] = ALPHA_BLEND_64_W( E[N12], px); \
182  E[N15] = E[N14] = E[N11] = px; \
183  E[N10] = E[N3] = E[N12]; \
184  E[N7] = E[N13]; \
185  } else if (left) { \
186  E[N11] = ALPHA_BLEND_192_W(E[N11], px); \
187  E[N13] = ALPHA_BLEND_192_W(E[N13], px); \
188  E[N10] = ALPHA_BLEND_64_W( E[N10], px); \
189  E[N12] = ALPHA_BLEND_64_W( E[N12], px); \
190  E[N14] = px; \
191  E[N15] = px; \
192  } else if (up) { \
193  E[N14] = ALPHA_BLEND_192_W(E[N14], px); \
194  E[N7 ] = ALPHA_BLEND_192_W(E[N7 ], px); \
195  E[N10] = ALPHA_BLEND_64_W( E[N10], px); \
196  E[N3 ] = ALPHA_BLEND_64_W( E[N3 ], px); \
197  E[N11] = px; \
198  E[N15] = px; \
199  } else { /* diagonal */ \
200  E[N11] = ALPHA_BLEND_128_W(E[N11], px); \
201  E[N14] = ALPHA_BLEND_128_W(E[N14], px); \
202  E[N15] = px; \
203  } \
204  } else { \
205  E[N15] = ALPHA_BLEND_128_W(E[N15], px); \
206  } \
207  } \
208  } \
209 } while (0)
210 
211 static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
212 {
213  int x, y;
214  const AVFrame *input = td->in;
215  AVFrame *output = td->out;
216  const uint32_t *r2y = td->rgbtoyuv;
217  const int slice_start = (input->height * jobnr ) / nb_jobs;
218  const int slice_end = (input->height * (jobnr+1)) / nb_jobs;
219  const int nl = output->linesize[0] >> 2;
220  const int nl1 = nl + nl;
221  const int nl2 = nl1 + nl;
222 
223  for (y = slice_start; y < slice_end; y++) {
224 
225  uint32_t *E = (uint32_t *)(output->data[0] + y * output->linesize[0] * n);
226  const uint32_t *sa2 = (uint32_t *)(input->data[0] + y * input->linesize[0] - 8); /* center */
227  const uint32_t *sa1 = sa2 - (input->linesize[0]>>2); /* up x1 */
228  const uint32_t *sa0 = sa1 - (input->linesize[0]>>2); /* up x2 */
229  const uint32_t *sa3 = sa2 + (input->linesize[0]>>2); /* down x1 */
230  const uint32_t *sa4 = sa3 + (input->linesize[0]>>2); /* down x2 */
231 
232  if (y <= 1) {
233  sa0 = sa1;
234  if (y == 0) {
235  sa0 = sa1 = sa2;
236  }
237  }
238 
239  if (y >= input->height - 2) {
240  sa4 = sa3;
241  if (y == input->height - 1) {
242  sa4 = sa3 = sa2;
243  }
244  }
245 
246  for (x = 0; x < input->width; x++) {
247  const uint32_t B1 = sa0[2];
248  const uint32_t PB = sa1[2];
249  const uint32_t PE = sa2[2];
250  const uint32_t PH = sa3[2];
251  const uint32_t H5 = sa4[2];
252 
253  const int pprev = 2 - (x > 0);
254  const uint32_t A1 = sa0[pprev];
255  const uint32_t PA = sa1[pprev];
256  const uint32_t PD = sa2[pprev];
257  const uint32_t PG = sa3[pprev];
258  const uint32_t G5 = sa4[pprev];
259 
260  const int pprev2 = pprev - (x > 1);
261  const uint32_t A0 = sa1[pprev2];
262  const uint32_t D0 = sa2[pprev2];
263  const uint32_t G0 = sa3[pprev2];
264 
265  const int pnext = 3 - (x == input->width - 1);
266  const uint32_t C1 = sa0[pnext];
267  const uint32_t PC = sa1[pnext];
268  const uint32_t PF = sa2[pnext];
269  const uint32_t PI = sa3[pnext];
270  const uint32_t I5 = sa4[pnext];
271 
272  const int pnext2 = pnext + 1 - (x >= input->width - 2);
273  const uint32_t C4 = sa1[pnext2];
274  const uint32_t F4 = sa2[pnext2];
275  const uint32_t I4 = sa3[pnext2];
276 
277  if (n == 2) {
278  E[0] = E[1] = // 0, 1
279  E[nl] = E[nl + 1] = PE; // 2, 3
280 
281  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);
282  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);
283  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);
284  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);
285  } else if (n == 3) {
286  E[0] = E[1] = E[2] = // 0, 1, 2
287  E[nl] = E[nl+1] = E[nl+2] = // 3, 4, 5
288  E[nl1] = E[nl1+1] = E[nl1+2] = PE; // 6, 7, 8
289 
290  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);
291  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);
292  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);
293  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);
294  } else if (n == 4) {
295  E[0] = E[1] = E[2] = E[3] = // 0, 1, 2, 3
296  E[nl] = E[nl+1] = E[nl+2] = E[nl+3] = // 4, 5, 6, 7
297  E[nl1] = E[nl1+1] = E[nl1+2] = E[nl1+3] = // 8, 9, 10, 11
298  E[nl2] = E[nl2+1] = E[nl2+2] = E[nl2+3] = PE; // 12, 13, 14, 15
299 
300  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);
301  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);
302  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);
303  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);
304  }
305 
306  sa0 += 1;
307  sa1 += 1;
308  sa2 += 1;
309  sa3 += 1;
310  sa4 += 1;
311 
312  E += n;
313  }
314  }
315 }
316 
317 #define XBR_FUNC(size) \
318 static int xbr##size##x(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
319 { \
320  xbr_filter(arg, jobnr, nb_jobs, size); \
321  return 0; \
322 }
323 
324 XBR_FUNC(2)
325 XBR_FUNC(3)
326 XBR_FUNC(4)
327 
328 
329 static int config_output(AVFilterLink *outlink)
330 {
331  AVFilterContext *ctx = outlink->src;
332  XBRContext *s = ctx->priv;
333  AVFilterLink *inlink = ctx->inputs[0];
334 
335  outlink->w = inlink->w * s->n;
336  outlink->h = inlink->h * s->n;
337  return 0;
338 }
339 
341 {
342  static const enum AVPixelFormat pix_fmts[] = {
344  };
345 
346  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
347  if (!fmts_list)
348  return AVERROR(ENOMEM);
349  return ff_set_common_formats(ctx, fmts_list);
350 }
351 
352 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
353 {
354  AVFilterContext *ctx = inlink->dst;
355  AVFilterLink *outlink = ctx->outputs[0];
356  XBRContext *s = ctx->priv;
357  ThreadData td;
358 
359  AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
360  if (!out) {
361  av_frame_free(&in);
362  return AVERROR(ENOMEM);
363  }
364 
365  av_frame_copy_props(out, in);
366 
367  td.in = in;
368  td.out = out;
369  td.rgbtoyuv = s->rgbtoyuv;
370  ctx->internal->execute(ctx, s->func, &td, NULL, FFMIN(inlink->h, ctx->graph->nb_threads));
371 
372  out->width = outlink->w;
373  out->height = outlink->h;
374 
375  av_frame_free(&in);
376  return ff_filter_frame(outlink, out);
377 }
378 
380 {
381  XBRContext *s = ctx->priv;
382  static const xbrfunc_t xbrfuncs[] = {xbr2x, xbr3x, xbr4x};
383 
384  uint32_t c;
385  int bg, rg, g;
386 
387  for (bg = -255; bg < 256; bg++) {
388  for (rg = -255; rg < 256; rg++) {
389  const uint32_t u = (uint32_t)((-169*rg + 500*bg)/1000) + 128;
390  const uint32_t v = (uint32_t)(( 500*rg - 81*bg)/1000) + 128;
391  int startg = FFMAX3(-bg, -rg, 0);
392  int endg = FFMIN3(255-bg, 255-rg, 255);
393  uint32_t y = (uint32_t)(( 299*rg + 1000*startg + 114*bg)/1000);
394  c = bg + (rg<<16) + 0x010101 * startg;
395  for (g = startg; g <= endg; g++) {
396  s->rgbtoyuv[c] = ((y++) << 16) + (u << 8) + v;
397  c+= 0x010101;
398  }
399  }
400  }
401 
402  s->func = xbrfuncs[s->n - 2];
403  return 0;
404 }
405 
406 static const AVFilterPad xbr_inputs[] = {
407  {
408  .name = "default",
409  .type = AVMEDIA_TYPE_VIDEO,
410  .filter_frame = filter_frame,
411  },
412  { NULL }
413 };
414 
415 static const AVFilterPad xbr_outputs[] = {
416  {
417  .name = "default",
418  .type = AVMEDIA_TYPE_VIDEO,
419  .config_props = config_output,
420  },
421  { NULL }
422 };
423 
425  .name = "xbr",
426  .description = NULL_IF_CONFIG_SMALL("Scale the input using xBR algorithm."),
427  .inputs = xbr_inputs,
428  .outputs = xbr_outputs,
429  .query_formats = query_formats,
430  .priv_size = sizeof(XBRContext),
431  .priv_class = &xbr_class,
432  .init = init,
434 };
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
AVFrame * out
Definition: af_sofalizer.c:499
#define VMASK
This structure describes decoded (raw) audio or video data.
Definition: frame.h:181
AVOption.
Definition: opt.h:245
AVFormatContext * ctx
Definition: movenc-test.c:48
#define A1
Definition: binkdsp.c:31
static const AVOption xbr_options[]
Definition: vf_xbr.c:56
xbrfunc_t func
Definition: vf_xbr.c:45
const char * g
Definition: vf_curves.c:108
#define OFFSET(x)
Definition: vf_xbr.c:54
static const AVFilterPad xbr_inputs[]
Definition: vf_xbr.c:406
#define PF(suf)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:76
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define B1
Definition: faandct.c:41
struct AVFilterGraph * graph
filtergraph this filter belongs to
Definition: avfilter.h:321
const char * name
Pad name.
Definition: internal.h:59
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:312
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1163
AVFrame * in
Definition: af_sofalizer.c:499
AVOptions.
int(* xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_xbr.c:40
#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:123
#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:89
int nb_threads
Maximum number of threads used by filters in this graph.
Definition: avfilter.h:788
#define FFMIN3(a, b, c)
Definition: common.h:97
A filter pad used for either input or output.
Definition: internal.h:53
int n
Definition: vf_xbr.c:44
#define C1
int width
width and height of the video frame
Definition: frame.h:230
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:568
#define td
Definition: regdef.h:70
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:154
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
void * priv
private data for use by the filter
Definition: avfilter.h:319
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:113
const char * arg
Definition: jacosubdec.c:66
static int config_output(AVFilterLink *outlink)
Definition: vf_xbr.c:329
simple assert() macros that are a bit more flexible than ISO C assert().
AVFilter ff_vf_xbr
Definition: vf_xbr.c:424
static int query_formats(AVFilterContext *ctx)
Definition: vf_xbr.c:340
#define YMASK
static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
Definition: vf_xbr.c:211
#define E
Definition: avdct.c:32
#define FFMIN(a, b)
Definition: common.h:96
#define FLAGS
Definition: vf_xbr.c:55
#define UMASK
int n
Definition: avisynth_c.h:547
FILE * out
Definition: movenc-test.c:54
#define C4
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:209
const uint32_t * rgbtoyuv
Definition: vf_hqx.c:46
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:141
#define XBR_FUNC(size)
Definition: vf_xbr.c:317
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_xbr.c:352
static uint32_t pixel_diff(uint32_t x, uint32_t y, const uint32_t *r2y)
Definition: vf_xbr.c:63
const char * name
Filter name.
Definition: avfilter.h:145
#define PD(a, b)
Pack two delta values (a,b) into one 16bit word according with endianness of the host machine...
Definition: indeo3data.h:290
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:316
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:262
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:344
static int flags
Definition: cpu.c:47
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:192
static double c[64]
avfilter_execute_func * execute
Definition: internal.h:153
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2094
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:304
#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:165
int height
Definition: frame.h:230
#define av_always_inline
Definition: attributes.h:39
internal API functions
static const AVFilterPad xbr_outputs[]
Definition: vf_xbr.c:415
static int init(AVFilterContext *ctx)
Definition: vf_xbr.c:379
AVPixelFormat
Pixel format.
Definition: pixfmt.h:61
AVFILTER_DEFINE_CLASS(xbr)
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:565
#define FFMAX3(a, b, c)
Definition: common.h:95
uint32_t rgbtoyuv[1<< 24]
Definition: vf_xbr.c:46
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:311