FFmpeg
vf_convolution.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2013 Oka Motofumi (chikuzen.mo at gmail dot com)
3  * Copyright (c) 2015 Paul B Mahol
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/avstring.h"
23 #include "libavutil/imgutils.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixdesc.h"
27 #include "avfilter.h"
28 #include "convolution.h"
29 #include "formats.h"
30 #include "internal.h"
31 #include "video.h"
32 
33 #define OFFSET(x) offsetof(ConvolutionContext, x)
34 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
35 
36 static const AVOption convolution_options[] = {
37  { "0m", "set matrix for 1st plane", OFFSET(matrix_str[0]), AV_OPT_TYPE_STRING, {.str="0 0 0 0 1 0 0 0 0"}, 0, 0, FLAGS },
38  { "1m", "set matrix for 2nd plane", OFFSET(matrix_str[1]), AV_OPT_TYPE_STRING, {.str="0 0 0 0 1 0 0 0 0"}, 0, 0, FLAGS },
39  { "2m", "set matrix for 3rd plane", OFFSET(matrix_str[2]), AV_OPT_TYPE_STRING, {.str="0 0 0 0 1 0 0 0 0"}, 0, 0, FLAGS },
40  { "3m", "set matrix for 4th plane", OFFSET(matrix_str[3]), AV_OPT_TYPE_STRING, {.str="0 0 0 0 1 0 0 0 0"}, 0, 0, FLAGS },
41  { "0rdiv", "set rdiv for 1st plane", OFFSET(rdiv[0]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
42  { "1rdiv", "set rdiv for 2nd plane", OFFSET(rdiv[1]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
43  { "2rdiv", "set rdiv for 3rd plane", OFFSET(rdiv[2]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
44  { "3rdiv", "set rdiv for 4th plane", OFFSET(rdiv[3]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
45  { "0bias", "set bias for 1st plane", OFFSET(bias[0]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
46  { "1bias", "set bias for 2nd plane", OFFSET(bias[1]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
47  { "2bias", "set bias for 3rd plane", OFFSET(bias[2]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
48  { "3bias", "set bias for 4th plane", OFFSET(bias[3]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
49  { "0mode", "set matrix mode for 1st plane", OFFSET(mode[0]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
50  { "1mode", "set matrix mode for 2nd plane", OFFSET(mode[1]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
51  { "2mode", "set matrix mode for 3rd plane", OFFSET(mode[2]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
52  { "3mode", "set matrix mode for 4th plane", OFFSET(mode[3]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
53  { "square", "square matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_SQUARE}, 0, 0, FLAGS, "mode" },
54  { "row", "single row matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_ROW} , 0, 0, FLAGS, "mode" },
55  { "column", "single column matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_COLUMN}, 0, 0, FLAGS, "mode" },
56  { NULL }
57 };
58 
59 AVFILTER_DEFINE_CLASS(convolution);
60 
61 static const int same3x3[9] = {0, 0, 0,
62  0, 1, 0,
63  0, 0, 0};
64 
65 static const int same5x5[25] = {0, 0, 0, 0, 0,
66  0, 0, 0, 0, 0,
67  0, 0, 1, 0, 0,
68  0, 0, 0, 0, 0,
69  0, 0, 0, 0, 0};
70 
71 static const int same7x7[49] = {0, 0, 0, 0, 0, 0, 0,
72  0, 0, 0, 0, 0, 0, 0,
73  0, 0, 0, 0, 0, 0, 0,
74  0, 0, 0, 1, 0, 0, 0,
75  0, 0, 0, 0, 0, 0, 0,
76  0, 0, 0, 0, 0, 0, 0,
77  0, 0, 0, 0, 0, 0, 0};
78 
80 {
81  static const enum AVPixelFormat pix_fmts[] = {
101  };
102 
103  return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
104 }
105 
106 typedef struct ThreadData {
107  AVFrame *in, *out;
108 } ThreadData;
109 
110 static void filter16_prewitt(uint8_t *dstp, int width,
111  float scale, float delta, const int *const matrix,
112  const uint8_t *c[], int peak, int radius,
113  int dstride, int stride)
114 {
115  uint16_t *dst = (uint16_t *)dstp;
116  int x;
117 
118  for (x = 0; x < width; x++) {
119  float suma = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[1][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * -1 +
120  AV_RN16A(&c[6][2 * x]) * 1 + AV_RN16A(&c[7][2 * x]) * 1 + AV_RN16A(&c[8][2 * x]) * 1;
121  float sumb = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -1 +
122  AV_RN16A(&c[5][2 * x]) * 1 + AV_RN16A(&c[6][2 * x]) * -1 + AV_RN16A(&c[8][2 * x]) * 1;
123 
124  dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak);
125  }
126 }
127 
128 static void filter16_roberts(uint8_t *dstp, int width,
129  float scale, float delta, const int *const matrix,
130  const uint8_t *c[], int peak, int radius,
131  int dstride, int stride)
132 {
133  uint16_t *dst = (uint16_t *)dstp;
134  int x;
135 
136  for (x = 0; x < width; x++) {
137  float suma = AV_RN16A(&c[0][2 * x]) * 1 + AV_RN16A(&c[1][2 * x]) * -1;
138  float sumb = AV_RN16A(&c[4][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -1;
139 
140  dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak);
141  }
142 }
143 
144 static void filter16_sobel(uint8_t *dstp, int width,
145  float scale, float delta, const int *const matrix,
146  const uint8_t *c[], int peak, int radius,
147  int dstride, int stride)
148 {
149  uint16_t *dst = (uint16_t *)dstp;
150  int x;
151 
152  for (x = 0; x < width; x++) {
153  float suma = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[1][2 * x]) * -2 + AV_RN16A(&c[2][2 * x]) * -1 +
154  AV_RN16A(&c[6][2 * x]) * 1 + AV_RN16A(&c[7][2 * x]) * 2 + AV_RN16A(&c[8][2 * x]) * 1;
155  float sumb = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -2 +
156  AV_RN16A(&c[5][2 * x]) * 2 + AV_RN16A(&c[6][2 * x]) * -1 + AV_RN16A(&c[8][2 * x]) * 1;
157 
158  dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak);
159  }
160 }
161 
162 static void filter_prewitt(uint8_t *dst, int width,
163  float scale, float delta, const int *const matrix,
164  const uint8_t *c[], int peak, int radius,
165  int dstride, int stride)
166 {
167  const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
168  const uint8_t *c3 = c[3], *c5 = c[5];
169  const uint8_t *c6 = c[6], *c7 = c[7], *c8 = c[8];
170  int x;
171 
172  for (x = 0; x < width; x++) {
173  float suma = c0[x] * -1 + c1[x] * -1 + c2[x] * -1 +
174  c6[x] * 1 + c7[x] * 1 + c8[x] * 1;
175  float sumb = c0[x] * -1 + c2[x] * 1 + c3[x] * -1 +
176  c5[x] * 1 + c6[x] * -1 + c8[x] * 1;
177 
178  dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta);
179  }
180 }
181 
182 static void filter_roberts(uint8_t *dst, int width,
183  float scale, float delta, const int *const matrix,
184  const uint8_t *c[], int peak, int radius,
185  int dstride, int stride)
186 {
187  int x;
188 
189  for (x = 0; x < width; x++) {
190  float suma = c[0][x] * 1 + c[1][x] * -1;
191  float sumb = c[4][x] * 1 + c[3][x] * -1;
192 
193  dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta);
194  }
195 }
196 
197 static void filter_sobel(uint8_t *dst, int width,
198  float scale, float delta, const int *const matrix,
199  const uint8_t *c[], int peak, int radius,
200  int dstride, int stride)
201 {
202  const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
203  const uint8_t *c3 = c[3], *c5 = c[5];
204  const uint8_t *c6 = c[6], *c7 = c[7], *c8 = c[8];
205  int x;
206 
207  for (x = 0; x < width; x++) {
208  float suma = c0[x] * -1 + c1[x] * -2 + c2[x] * -1 +
209  c6[x] * 1 + c7[x] * 2 + c8[x] * 1;
210  float sumb = c0[x] * -1 + c2[x] * 1 + c3[x] * -2 +
211  c5[x] * 2 + c6[x] * -1 + c8[x] * 1;
212 
213  dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta);
214  }
215 }
216 
217 static void filter16_3x3(uint8_t *dstp, int width,
218  float rdiv, float bias, const int *const matrix,
219  const uint8_t *c[], int peak, int radius,
220  int dstride, int stride)
221 {
222  uint16_t *dst = (uint16_t *)dstp;
223  int x;
224 
225  for (x = 0; x < width; x++) {
226  int sum = AV_RN16A(&c[0][2 * x]) * matrix[0] +
227  AV_RN16A(&c[1][2 * x]) * matrix[1] +
228  AV_RN16A(&c[2][2 * x]) * matrix[2] +
229  AV_RN16A(&c[3][2 * x]) * matrix[3] +
230  AV_RN16A(&c[4][2 * x]) * matrix[4] +
231  AV_RN16A(&c[5][2 * x]) * matrix[5] +
232  AV_RN16A(&c[6][2 * x]) * matrix[6] +
233  AV_RN16A(&c[7][2 * x]) * matrix[7] +
234  AV_RN16A(&c[8][2 * x]) * matrix[8];
235  sum = (int)(sum * rdiv + bias + 0.5f);
236  dst[x] = av_clip(sum, 0, peak);
237  }
238 }
239 
240 static void filter16_5x5(uint8_t *dstp, int width,
241  float rdiv, float bias, const int *const matrix,
242  const uint8_t *c[], int peak, int radius,
243  int dstride, int stride)
244 {
245  uint16_t *dst = (uint16_t *)dstp;
246  int x;
247 
248  for (x = 0; x < width; x++) {
249  int i, sum = 0;
250 
251  for (i = 0; i < 25; i++)
252  sum += AV_RN16A(&c[i][2 * x]) * matrix[i];
253 
254  sum = (int)(sum * rdiv + bias + 0.5f);
255  dst[x] = av_clip(sum, 0, peak);
256  }
257 }
258 
259 static void filter16_7x7(uint8_t *dstp, int width,
260  float rdiv, float bias, const int *const matrix,
261  const uint8_t *c[], int peak, int radius,
262  int dstride, int stride)
263 {
264  uint16_t *dst = (uint16_t *)dstp;
265  int x;
266 
267  for (x = 0; x < width; x++) {
268  int i, sum = 0;
269 
270  for (i = 0; i < 49; i++)
271  sum += AV_RN16A(&c[i][2 * x]) * matrix[i];
272 
273  sum = (int)(sum * rdiv + bias + 0.5f);
274  dst[x] = av_clip(sum, 0, peak);
275  }
276 }
277 
278 static void filter16_row(uint8_t *dstp, int width,
279  float rdiv, float bias, const int *const matrix,
280  const uint8_t *c[], int peak, int radius,
281  int dstride, int stride)
282 {
283  uint16_t *dst = (uint16_t *)dstp;
284  int x;
285 
286  for (x = 0; x < width; x++) {
287  int i, sum = 0;
288 
289  for (i = 0; i < 2 * radius + 1; i++)
290  sum += AV_RN16A(&c[i][2 * x]) * matrix[i];
291 
292  sum = (int)(sum * rdiv + bias + 0.5f);
293  dst[x] = av_clip(sum, 0, peak);
294  }
295 }
296 
297 static void filter16_column(uint8_t *dstp, int height,
298  float rdiv, float bias, const int *const matrix,
299  const uint8_t *c[], int peak, int radius,
300  int dstride, int stride)
301 {
302  uint16_t *dst = (uint16_t *)dstp;
303  int y;
304 
305  for (y = 0; y < height; y++) {
306  int i, sum = 0;
307 
308  for (i = 0; i < 2 * radius + 1; i++)
309  sum += AV_RN16A(&c[i][0 + y * stride]) * matrix[i];
310 
311  sum = (int)(sum * rdiv + bias + 0.5f);
312  dst[0] = av_clip(sum, 0, peak);
313  dst += dstride / 2;
314  }
315 }
316 
317 static void filter_7x7(uint8_t *dst, int width,
318  float rdiv, float bias, const int *const matrix,
319  const uint8_t *c[], int peak, int radius,
320  int dstride, int stride)
321 {
322  int x;
323 
324  for (x = 0; x < width; x++) {
325  int i, sum = 0;
326 
327  for (i = 0; i < 49; i++)
328  sum += c[i][x] * matrix[i];
329 
330  sum = (int)(sum * rdiv + bias + 0.5f);
331  dst[x] = av_clip_uint8(sum);
332  }
333 }
334 
335 static void filter_5x5(uint8_t *dst, int width,
336  float rdiv, float bias, const int *const matrix,
337  const uint8_t *c[], int peak, int radius,
338  int dstride, int stride)
339 {
340  int x;
341 
342  for (x = 0; x < width; x++) {
343  int i, sum = 0;
344 
345  for (i = 0; i < 25; i++)
346  sum += c[i][x] * matrix[i];
347 
348  sum = (int)(sum * rdiv + bias + 0.5f);
349  dst[x] = av_clip_uint8(sum);
350  }
351 }
352 
353 static void filter_3x3(uint8_t *dst, int width,
354  float rdiv, float bias, const int *const matrix,
355  const uint8_t *c[], int peak, int radius,
356  int dstride, int stride)
357 {
358  const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
359  const uint8_t *c3 = c[3], *c4 = c[4], *c5 = c[5];
360  const uint8_t *c6 = c[6], *c7 = c[7], *c8 = c[8];
361  int x;
362 
363  for (x = 0; x < width; x++) {
364  int sum = c0[x] * matrix[0] + c1[x] * matrix[1] + c2[x] * matrix[2] +
365  c3[x] * matrix[3] + c4[x] * matrix[4] + c5[x] * matrix[5] +
366  c6[x] * matrix[6] + c7[x] * matrix[7] + c8[x] * matrix[8];
367  sum = (int)(sum * rdiv + bias + 0.5f);
368  dst[x] = av_clip_uint8(sum);
369  }
370 }
371 
372 static void filter_row(uint8_t *dst, int width,
373  float rdiv, float bias, const int *const matrix,
374  const uint8_t *c[], int peak, int radius,
375  int dstride, int stride)
376 {
377  int x;
378 
379  for (x = 0; x < width; x++) {
380  int i, sum = 0;
381 
382  for (i = 0; i < 2 * radius + 1; i++)
383  sum += c[i][x] * matrix[i];
384 
385  sum = (int)(sum * rdiv + bias + 0.5f);
386  dst[x] = av_clip_uint8(sum);
387  }
388 }
389 
390 static void filter_column(uint8_t *dst, int height,
391  float rdiv, float bias, const int *const matrix,
392  const uint8_t *c[], int peak, int radius,
393  int dstride, int stride)
394 {
395  int y;
396 
397  for (y = 0; y < height; y++) {
398  int i, sum = 0;
399 
400  for (i = 0; i < 2 * radius + 1; i++)
401  sum += c[i][0 + y * stride] * matrix[i];
402 
403  sum = (int)(sum * rdiv + bias + 0.5f);
404  dst[0] = av_clip_uint8(sum);
405  dst += dstride;
406  }
407 }
408 
409 static void setup_3x3(int radius, const uint8_t *c[], const uint8_t *src, int stride,
410  int x, int w, int y, int h, int bpc)
411 {
412  int i;
413 
414  for (i = 0; i < 9; i++) {
415  int xoff = FFABS(x + ((i % 3) - 1));
416  int yoff = FFABS(y + (i / 3) - 1);
417 
418  xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
419  yoff = yoff >= h ? 2 * h - 1 - yoff : yoff;
420 
421  c[i] = src + xoff * bpc + yoff * stride;
422  }
423 }
424 
425 static void setup_5x5(int radius, const uint8_t *c[], const uint8_t *src, int stride,
426  int x, int w, int y, int h, int bpc)
427 {
428  int i;
429 
430  for (i = 0; i < 25; i++) {
431  int xoff = FFABS(x + ((i % 5) - 2));
432  int yoff = FFABS(y + (i / 5) - 2);
433 
434  xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
435  yoff = yoff >= h ? 2 * h - 1 - yoff : yoff;
436 
437  c[i] = src + xoff * bpc + yoff * stride;
438  }
439 }
440 
441 static void setup_7x7(int radius, const uint8_t *c[], const uint8_t *src, int stride,
442  int x, int w, int y, int h, int bpc)
443 {
444  int i;
445 
446  for (i = 0; i < 49; i++) {
447  int xoff = FFABS(x + ((i % 7) - 3));
448  int yoff = FFABS(y + (i / 7) - 3);
449 
450  xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
451  yoff = yoff >= h ? 2 * h - 1 - yoff : yoff;
452 
453  c[i] = src + xoff * bpc + yoff * stride;
454  }
455 }
456 
457 static void setup_row(int radius, const uint8_t *c[], const uint8_t *src, int stride,
458  int x, int w, int y, int h, int bpc)
459 {
460  int i;
461 
462  for (i = 0; i < radius * 2 + 1; i++) {
463  int xoff = FFABS(x + i - radius);
464 
465  xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
466 
467  c[i] = src + xoff * bpc + y * stride;
468  }
469 }
470 
471 static void setup_column(int radius, const uint8_t *c[], const uint8_t *src, int stride,
472  int x, int w, int y, int h, int bpc)
473 {
474  int i;
475 
476  for (i = 0; i < radius * 2 + 1; i++) {
477  int xoff = FFABS(x + i - radius);
478 
479  xoff = xoff >= h ? 2 * h - 1 - xoff : xoff;
480 
481  c[i] = src + y * bpc + xoff * stride;
482  }
483 }
484 
485 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
486 {
487  ConvolutionContext *s = ctx->priv;
488  ThreadData *td = arg;
489  AVFrame *in = td->in;
490  AVFrame *out = td->out;
491  int plane;
492 
493  for (plane = 0; plane < s->nb_planes; plane++) {
494  const int mode = s->mode[plane];
495  const int bpc = s->bpc;
496  const int radius = s->size[plane] / 2;
497  const int height = s->planeheight[plane];
498  const int width = s->planewidth[plane];
499  const int stride = in->linesize[plane];
500  const int dstride = out->linesize[plane];
501  const int sizeh = mode == MATRIX_COLUMN ? width : height;
502  const int sizew = mode == MATRIX_COLUMN ? height : width;
503  const int slice_start = (sizeh * jobnr) / nb_jobs;
504  const int slice_end = (sizeh * (jobnr+1)) / nb_jobs;
505  const float rdiv = s->rdiv[plane];
506  const float bias = s->bias[plane];
507  const uint8_t *src = in->data[plane];
508  const int dst_pos = slice_start * (mode == MATRIX_COLUMN ? bpc : dstride);
509  uint8_t *dst = out->data[plane] + dst_pos;
510  const int *matrix = s->matrix[plane];
511  const uint8_t *c[49];
512  int y, x;
513 
514  if (s->copy[plane]) {
515  if (mode == MATRIX_COLUMN)
516  av_image_copy_plane(dst, dstride, src + slice_start * bpc, stride,
517  (slice_end - slice_start) * bpc, height);
518  else
519  av_image_copy_plane(dst, dstride, src + slice_start * stride, stride,
520  width * bpc, slice_end - slice_start);
521  continue;
522  }
523 
524  for (y = slice_start; y < slice_end; y++) {
525  const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : radius * bpc;
526  const int yoff = mode == MATRIX_COLUMN ? radius * stride : 0;
527 
528  for (x = 0; x < radius; x++) {
529  const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc;
530  const int yoff = mode == MATRIX_COLUMN ? x * stride : 0;
531 
532  s->setup[plane](radius, c, src, stride, x, width, y, height, bpc);
533  s->filter[plane](dst + yoff + xoff, 1, rdiv,
534  bias, matrix, c, s->max, radius,
535  dstride, stride);
536  }
537  s->setup[plane](radius, c, src, stride, radius, width, y, height, bpc);
538  s->filter[plane](dst + yoff + xoff, sizew - 2 * radius,
539  rdiv, bias, matrix, c, s->max, radius,
540  dstride, stride);
541  for (x = sizew - radius; x < sizew; x++) {
542  const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc;
543  const int yoff = mode == MATRIX_COLUMN ? x * stride : 0;
544 
545  s->setup[plane](radius, c, src, stride, x, width, y, height, bpc);
546  s->filter[plane](dst + yoff + xoff, 1, rdiv,
547  bias, matrix, c, s->max, radius,
548  dstride, stride);
549  }
550  if (mode != MATRIX_COLUMN)
551  dst += dstride;
552  }
553  }
554 
555  return 0;
556 }
557 
559 {
560  AVFilterContext *ctx = inlink->dst;
561  ConvolutionContext *s = ctx->priv;
563  int p;
564 
565  s->depth = desc->comp[0].depth;
566  s->max = (1 << s->depth) - 1;
567 
568  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
569  s->planewidth[0] = s->planewidth[3] = inlink->w;
570  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
571  s->planeheight[0] = s->planeheight[3] = inlink->h;
572 
575  s->bpc = (s->depth + 7) / 8;
576 
577  if (!strcmp(ctx->filter->name, "convolution")) {
578  if (s->depth > 8) {
579  for (p = 0; p < s->nb_planes; p++) {
580  if (s->mode[p] == MATRIX_ROW)
581  s->filter[p] = filter16_row;
582  else if (s->mode[p] == MATRIX_COLUMN)
583  s->filter[p] = filter16_column;
584  else if (s->size[p] == 3)
585  s->filter[p] = filter16_3x3;
586  else if (s->size[p] == 5)
587  s->filter[p] = filter16_5x5;
588  else if (s->size[p] == 7)
589  s->filter[p] = filter16_7x7;
590  }
591  }
592 #if CONFIG_CONVOLUTION_FILTER && ARCH_X86_64
594 #endif
595  } else if (!strcmp(ctx->filter->name, "prewitt")) {
596  if (s->depth > 8)
597  for (p = 0; p < s->nb_planes; p++)
598  s->filter[p] = filter16_prewitt;
599  } else if (!strcmp(ctx->filter->name, "roberts")) {
600  if (s->depth > 8)
601  for (p = 0; p < s->nb_planes; p++)
602  s->filter[p] = filter16_roberts;
603  } else if (!strcmp(ctx->filter->name, "sobel")) {
604  if (s->depth > 8)
605  for (p = 0; p < s->nb_planes; p++)
606  s->filter[p] = filter16_sobel;
607  }
608 
609  return 0;
610 }
611 
613 {
614  AVFilterContext *ctx = inlink->dst;
615  ConvolutionContext *s = ctx->priv;
616  AVFilterLink *outlink = ctx->outputs[0];
617  AVFrame *out;
618  ThreadData td;
619 
620  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
621  if (!out) {
622  av_frame_free(&in);
623  return AVERROR(ENOMEM);
624  }
625  av_frame_copy_props(out, in);
626 
627  td.in = in;
628  td.out = out;
629  ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN3(s->planeheight[1], s->planewidth[1], s->nb_threads));
630 
631  av_frame_free(&in);
632  return ff_filter_frame(outlink, out);
633 }
634 
636 {
637  ConvolutionContext *s = ctx->priv;
638  int i;
639 
640  if (!strcmp(ctx->filter->name, "convolution")) {
641  for (i = 0; i < 4; i++) {
642  int *matrix = (int *)s->matrix[i];
643  char *p, *arg, *saveptr = NULL;
644  float sum = 0;
645 
646  p = s->matrix_str[i];
647  while (s->matrix_length[i] < 49) {
648  if (!(arg = av_strtok(p, " ", &saveptr)))
649  break;
650 
651  p = NULL;
652  sscanf(arg, "%d", &matrix[s->matrix_length[i]]);
653  sum += matrix[s->matrix_length[i]];
654  s->matrix_length[i]++;
655  }
656 
657  if (!(s->matrix_length[i] & 1)) {
658  av_log(ctx, AV_LOG_ERROR, "number of matrix elements must be odd\n");
659  return AVERROR(EINVAL);
660  }
661  if (s->mode[i] == MATRIX_ROW) {
662  s->filter[i] = filter_row;
663  s->setup[i] = setup_row;
664  s->size[i] = s->matrix_length[i];
665  } else if (s->mode[i] == MATRIX_COLUMN) {
666  s->filter[i] = filter_column;
667  s->setup[i] = setup_column;
668  s->size[i] = s->matrix_length[i];
669  } else if (s->matrix_length[i] == 9) {
670  s->size[i] = 3;
671  if (!memcmp(matrix, same3x3, sizeof(same3x3)))
672  s->copy[i] = 1;
673  else
674  s->filter[i] = filter_3x3;
675  s->setup[i] = setup_3x3;
676  } else if (s->matrix_length[i] == 25) {
677  s->size[i] = 5;
678  if (!memcmp(matrix, same5x5, sizeof(same5x5)))
679  s->copy[i] = 1;
680  else
681  s->filter[i] = filter_5x5;
682  s->setup[i] = setup_5x5;
683  } else if (s->matrix_length[i] == 49) {
684  s->size[i] = 7;
685  if (!memcmp(matrix, same7x7, sizeof(same7x7)))
686  s->copy[i] = 1;
687  else
688  s->filter[i] = filter_7x7;
689  s->setup[i] = setup_7x7;
690  } else {
691  return AVERROR(EINVAL);
692  }
693 
694  if (sum == 0)
695  sum = 1;
696  if (s->rdiv[i] == 0)
697  s->rdiv[i] = 1. / sum;
698 
699  if (s->copy[i] && (s->rdiv[i] != 1. || s->bias[i] != 0.))
700  s->copy[i] = 0;
701  }
702  } else if (!strcmp(ctx->filter->name, "prewitt")) {
703  for (i = 0; i < 4; i++) {
704  if ((1 << i) & s->planes)
705  s->filter[i] = filter_prewitt;
706  else
707  s->copy[i] = 1;
708  s->size[i] = 3;
709  s->setup[i] = setup_3x3;
710  s->rdiv[i] = s->scale;
711  s->bias[i] = s->delta;
712  }
713  } else if (!strcmp(ctx->filter->name, "roberts")) {
714  for (i = 0; i < 4; i++) {
715  if ((1 << i) & s->planes)
716  s->filter[i] = filter_roberts;
717  else
718  s->copy[i] = 1;
719  s->size[i] = 3;
720  s->setup[i] = setup_3x3;
721  s->rdiv[i] = s->scale;
722  s->bias[i] = s->delta;
723  }
724  } else if (!strcmp(ctx->filter->name, "sobel")) {
725  for (i = 0; i < 4; i++) {
726  if ((1 << i) & s->planes)
727  s->filter[i] = filter_sobel;
728  else
729  s->copy[i] = 1;
730  s->size[i] = 3;
731  s->setup[i] = setup_3x3;
732  s->rdiv[i] = s->scale;
733  s->bias[i] = s->delta;
734  }
735  }
736 
737  return 0;
738 }
739 
740 static const AVFilterPad convolution_inputs[] = {
741  {
742  .name = "default",
743  .type = AVMEDIA_TYPE_VIDEO,
744  .config_props = config_input,
745  .filter_frame = filter_frame,
746  },
747  { NULL }
748 };
749 
751  {
752  .name = "default",
753  .type = AVMEDIA_TYPE_VIDEO,
754  },
755  { NULL }
756 };
757 
758 #if CONFIG_CONVOLUTION_FILTER
759 
761  .name = "convolution",
762  .description = NULL_IF_CONFIG_SMALL("Apply convolution filter."),
763  .priv_size = sizeof(ConvolutionContext),
764  .priv_class = &convolution_class,
765  .init = init,
767  .inputs = convolution_inputs,
768  .outputs = convolution_outputs,
770 };
771 
772 #endif /* CONFIG_CONVOLUTION_FILTER */
773 
774 #if CONFIG_PREWITT_FILTER
775 
776 static const AVOption prewitt_options[] = {
777  { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS},
778  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS},
779  { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS},
780  { NULL }
781 };
782 
783 AVFILTER_DEFINE_CLASS(prewitt);
784 
786  .name = "prewitt",
787  .description = NULL_IF_CONFIG_SMALL("Apply prewitt operator."),
788  .priv_size = sizeof(ConvolutionContext),
789  .priv_class = &prewitt_class,
790  .init = init,
792  .inputs = convolution_inputs,
793  .outputs = convolution_outputs,
795 };
796 
797 #endif /* CONFIG_PREWITT_FILTER */
798 
799 #if CONFIG_SOBEL_FILTER
800 
801 static const AVOption sobel_options[] = {
802  { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS},
803  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS},
804  { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS},
805  { NULL }
806 };
807 
809 
811  .name = "sobel",
812  .description = NULL_IF_CONFIG_SMALL("Apply sobel operator."),
813  .priv_size = sizeof(ConvolutionContext),
814  .priv_class = &sobel_class,
815  .init = init,
817  .inputs = convolution_inputs,
818  .outputs = convolution_outputs,
820 };
821 
822 #endif /* CONFIG_SOBEL_FILTER */
823 
824 #if CONFIG_ROBERTS_FILTER
825 
826 static const AVOption roberts_options[] = {
827  { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS},
828  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS},
829  { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS},
830  { NULL }
831 };
832 
833 AVFILTER_DEFINE_CLASS(roberts);
834 
836  .name = "roberts",
837  .description = NULL_IF_CONFIG_SMALL("Apply roberts cross operator."),
838  .priv_size = sizeof(ConvolutionContext),
839  .priv_class = &roberts_class,
840  .init = init,
842  .inputs = convolution_inputs,
843  .outputs = convolution_outputs,
845 };
846 
847 #endif /* CONFIG_ROBERTS_FILTER */
#define NULL
Definition: coverity.c:32
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:430
AVFrame * out
Definition: af_adeclick.c:488
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:422
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
int matrix[4][49]
Definition: convolution.h:51
AVOption.
Definition: opt.h:246
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:424
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:397
static void filter16_sobel(uint8_t *dstp, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:407
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:425
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2562
Main libavfilter public API header.
static void sobel(int w, int h, uint16_t *dst, int dst_linesize, int8_t *dir, int dir_linesize, const uint8_t *src, int src_linesize)
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:403
static void filter16_column(uint8_t *dstp, int height, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
AVFilter ff_vf_prewitt
static void setup_7x7(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:367
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:391
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
char * matrix_str[4]
Definition: convolution.h:35
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:368
static void filter16_row(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:125
const char * name
Pad name.
Definition: internal.h:60
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:369
static void setup_5x5(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
static void filter_7x7(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1093
double peak
Definition: vf_tonemap.c:197
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:82
static void filter_5x5(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
float delta
AVOptions.
#define f(width, name)
Definition: cbs_vp9.c:255
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:421
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:402
int height
Definition: vf_avgblur.c:61
AVFrame * dst
Definition: vf_blend.c:55
int plane
Definition: vf_blend.c:57
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:100
#define FFMIN3(a, b, c)
Definition: common.h:97
static const uint64_t c1
Definition: murmur3.c:49
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
void(* setup[4])(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int width, int y, int height, int bpc)
Definition: convolution.h:55
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:400
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:392
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:429
#define av_log(a,...)
AVFilter ff_vf_convolution
A filter pad used for either input or output.
Definition: internal.h:54
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:569
#define td
Definition: regdef.h:70
static const int same7x7[49]
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
AVFilter ff_vf_sobel
BYTE * dstp
Definition: avisynth_c.h:908
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static const AVFilterPad convolution_inputs[]
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:431
const char * arg
Definition: jacosubdec.c:66
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:408
static void filter_row(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:390
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:409
const uint8_t * src
Definition: vf_bm3d.c:56
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
static const struct @321 planes[]
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:385
static void filter16_prewitt(uint8_t *dstp, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:406
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:371
static const AVFilterPad convolution_outputs[]
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
static void filter16_3x3(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:428
static const AVOption convolution_options[]
AVFormatContext * ctx
Definition: movenc.c:48
static int query_formats(AVFilterContext *ctx)
static av_cold int init(AVFilterContext *ctx)
static void filter_prewitt(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:426
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:386
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:405
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:398
static void filter_roberts(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:395
Used for passing data between threads.
Definition: dsddec.c:64
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
AVFilter ff_vf_roberts
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
static void filter_column(uint8_t *dst, int height, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:370
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:387
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
Filter definition.
Definition: avfilter.h:144
static void setup_3x3(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
AVFILTER_DEFINE_CLASS(convolution)
static const int same3x3[9]
static void setup_row(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
const char * name
Filter name.
Definition: avfilter.h:148
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:393
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:384
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:396
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:404
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:388
void ff_convolution_init_x86(ConvolutionContext *s)
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:394
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
Definition: avstring.c:184
static void filter_sobel(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
static void setup_column(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
int
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
Y , 8bpp.
Definition: pixfmt.h:74
static void filter16_5x5(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
static const int same5x5[25]
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:423
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
avfilter_execute_func * execute
Definition: internal.h:155
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2036
static void filter16_roberts(uint8_t *dstp, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
const AVPixFmtDescriptor * desc
Definition: vf_tonemap.c:196
static void filter16_7x7(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:258
static void filter_3x3(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_RN16A(p)
Definition: intreadwrite.h:522
static int config_input(AVFilterLink *inlink)
#define FLAGS
An instance of a filter.
Definition: avfilter.h:338
#define OFFSET(x)
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
AVFrame * in
Definition: af_afftdn.c:1082
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:338
#define stride
AVFilterLink * inlink
Definition: vf_blend.c:56
internal API functions
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
void(* filter[4])(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
Definition: convolution.h:57
int depth
Number of bits in the component.
Definition: pixdesc.h:58
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:341
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:399
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:427
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58