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 "formats.h"
29 #include "internal.h"
30 #include "video.h"
31 
32 enum MatrixMode {
37 };
38 
39 typedef struct ConvolutionContext {
40  const AVClass *class;
41 
42  char *matrix_str[4];
43  float rdiv[4];
44  float bias[4];
45  int mode[4];
46  float scale;
47  float delta;
48  int planes;
49 
50  int size[4];
51  int depth;
52  int max;
53  int bpc;
54  int nb_planes;
56  int planewidth[4];
57  int planeheight[4];
58  int matrix[4][49];
59  int matrix_length[4];
60  int copy[4];
61 
62  void (*setup[4])(int radius, const uint8_t *c[], const uint8_t *src, int stride,
63  int x, int width, int y, int height, int bpc);
64  void (*filter[4])(uint8_t *dst, int width,
65  float rdiv, float bias, const int *const matrix,
66  const uint8_t *c[], int peak, int radius,
67  int dstride, int stride);
69 
70 #define OFFSET(x) offsetof(ConvolutionContext, x)
71 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
72 
73 static const AVOption convolution_options[] = {
74  { "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 },
75  { "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 },
76  { "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 },
77  { "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 },
78  { "0rdiv", "set rdiv for 1st plane", OFFSET(rdiv[0]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
79  { "1rdiv", "set rdiv for 2nd plane", OFFSET(rdiv[1]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
80  { "2rdiv", "set rdiv for 3rd plane", OFFSET(rdiv[2]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
81  { "3rdiv", "set rdiv for 4th plane", OFFSET(rdiv[3]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
82  { "0bias", "set bias for 1st plane", OFFSET(bias[0]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
83  { "1bias", "set bias for 2nd plane", OFFSET(bias[1]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
84  { "2bias", "set bias for 3rd plane", OFFSET(bias[2]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
85  { "3bias", "set bias for 4th plane", OFFSET(bias[3]), AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, INT_MAX, FLAGS},
86  { "0mode", "set matrix mode for 1st plane", OFFSET(mode[0]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
87  { "1mode", "set matrix mode for 2nd plane", OFFSET(mode[1]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
88  { "2mode", "set matrix mode for 3rd plane", OFFSET(mode[2]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
89  { "3mode", "set matrix mode for 4th plane", OFFSET(mode[3]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
90  { "square", "square matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_SQUARE}, 0, 0, FLAGS, "mode" },
91  { "row", "single row matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_ROW} , 0, 0, FLAGS, "mode" },
92  { "column", "single column matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_COLUMN}, 0, 0, FLAGS, "mode" },
93  { NULL }
94 };
95 
96 AVFILTER_DEFINE_CLASS(convolution);
97 
98 static const int same3x3[9] = {0, 0, 0,
99  0, 1, 0,
100  0, 0, 0};
101 
102 static const int same5x5[25] = {0, 0, 0, 0, 0,
103  0, 0, 0, 0, 0,
104  0, 0, 1, 0, 0,
105  0, 0, 0, 0, 0,
106  0, 0, 0, 0, 0};
107 
108 static const int same7x7[49] = {0, 0, 0, 0, 0, 0, 0,
109  0, 0, 0, 0, 0, 0, 0,
110  0, 0, 0, 0, 0, 0, 0,
111  0, 0, 0, 1, 0, 0, 0,
112  0, 0, 0, 0, 0, 0, 0,
113  0, 0, 0, 0, 0, 0, 0,
114  0, 0, 0, 0, 0, 0, 0};
115 
117 {
118  static const enum AVPixelFormat pix_fmts[] = {
137  };
138 
140 }
141 
142 typedef struct ThreadData {
143  AVFrame *in, *out;
144 } ThreadData;
145 
146 static void filter16_prewitt(uint8_t *dstp, int width,
147  float scale, float delta, const int *const matrix,
148  const uint8_t *c[], int peak, int radius,
149  int dstride, int stride)
150 {
151  uint16_t *dst = (uint16_t *)dstp;
152  int x;
153 
154  for (x = 0; x < width; x++) {
155  int suma = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[1][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * -1 +
156  AV_RN16A(&c[6][2 * x]) * 1 + AV_RN16A(&c[7][2 * x]) * 1 + AV_RN16A(&c[8][2 * x]) * 1;
157  int sumb = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -1 +
158  AV_RN16A(&c[5][2 * x]) * 1 + AV_RN16A(&c[6][2 * x]) * -1 + AV_RN16A(&c[8][2 * x]) * 1;
159 
160  dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak);
161  }
162 }
163 
164 static void filter16_roberts(uint8_t *dstp, int width,
165  float scale, float delta, const int *const matrix,
166  const uint8_t *c[], int peak, int radius,
167  int dstride, int stride)
168 {
169  uint16_t *dst = (uint16_t *)dstp;
170  int x;
171 
172  for (x = 0; x < width; x++) {
173  int suma = AV_RN16A(&c[0][2 * x]) * 1 + AV_RN16A(&c[1][2 * x]) * -1;
174  int sumb = AV_RN16A(&c[4][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -1;
175 
176  dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak);
177  }
178 }
179 
180 static void filter16_sobel(uint8_t *dstp, int width,
181  float scale, float delta, const int *const matrix,
182  const uint8_t *c[], int peak, int radius,
183  int dstride, int stride)
184 {
185  uint16_t *dst = (uint16_t *)dstp;
186  int x;
187 
188  for (x = 0; x < width; x++) {
189  int suma = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[1][2 * x]) * -2 + AV_RN16A(&c[2][2 * x]) * -1 +
190  AV_RN16A(&c[6][2 * x]) * 1 + AV_RN16A(&c[7][2 * x]) * 2 + AV_RN16A(&c[8][2 * x]) * 1;
191  int sumb = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -2 +
192  AV_RN16A(&c[5][2 * x]) * 2 + AV_RN16A(&c[6][2 * x]) * -1 + AV_RN16A(&c[8][2 * x]) * 1;
193 
194  dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak);
195  }
196 }
197 
198 static void filter_prewitt(uint8_t *dst, int width,
199  float scale, float delta, const int *const matrix,
200  const uint8_t *c[], int peak, int radius,
201  int dstride, int stride)
202 {
203  const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
204  const uint8_t *c3 = c[3], *c5 = c[5];
205  const uint8_t *c6 = c[6], *c7 = c[7], *c8 = c[8];
206  int x;
207 
208  for (x = 0; x < width; x++) {
209  int suma = c0[x] * -1 + c1[x] * -1 + c2[x] * -1 +
210  c6[x] * 1 + c7[x] * 1 + c8[x] * 1;
211  int sumb = c0[x] * -1 + c2[x] * 1 + c3[x] * -1 +
212  c5[x] * 1 + c6[x] * -1 + c8[x] * 1;
213 
214  dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta);
215  }
216 }
217 
218 static void filter_roberts(uint8_t *dst, int width,
219  float scale, float delta, const int *const matrix,
220  const uint8_t *c[], int peak, int radius,
221  int dstride, int stride)
222 {
223  int x;
224 
225  for (x = 0; x < width; x++) {
226  int suma = c[0][x] * 1 + c[1][x] * -1;
227  int sumb = c[4][x] * 1 + c[3][x] * -1;
228 
229  dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta);
230  }
231 }
232 
233 static void filter_sobel(uint8_t *dst, int width,
234  float scale, float delta, const int *const matrix,
235  const uint8_t *c[], int peak, int radius,
236  int dstride, int stride)
237 {
238  const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
239  const uint8_t *c3 = c[3], *c5 = c[5];
240  const uint8_t *c6 = c[6], *c7 = c[7], *c8 = c[8];
241  int x;
242 
243  for (x = 0; x < width; x++) {
244  int suma = c0[x] * -1 + c1[x] * -2 + c2[x] * -1 +
245  c6[x] * 1 + c7[x] * 2 + c8[x] * 1;
246  int sumb = c0[x] * -1 + c2[x] * 1 + c3[x] * -2 +
247  c5[x] * 2 + c6[x] * -1 + c8[x] * 1;
248 
249  dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta);
250  }
251 }
252 
253 static void filter16_3x3(uint8_t *dstp, int width,
254  float rdiv, float bias, const int *const matrix,
255  const uint8_t *c[], int peak, int radius,
256  int dstride, int stride)
257 {
258  uint16_t *dst = (uint16_t *)dstp;
259  int x;
260 
261  for (x = 0; x < width; x++) {
262  int sum = AV_RN16A(&c[0][2 * x]) * matrix[0] +
263  AV_RN16A(&c[1][2 * x]) * matrix[1] +
264  AV_RN16A(&c[2][2 * x]) * matrix[2] +
265  AV_RN16A(&c[3][2 * x]) * matrix[3] +
266  AV_RN16A(&c[4][2 * x]) * matrix[4] +
267  AV_RN16A(&c[5][2 * x]) * matrix[5] +
268  AV_RN16A(&c[6][2 * x]) * matrix[6] +
269  AV_RN16A(&c[7][2 * x]) * matrix[7] +
270  AV_RN16A(&c[8][2 * x]) * matrix[8];
271  sum = (int)(sum * rdiv + bias + 0.5f);
272  dst[x] = av_clip(sum, 0, peak);
273  }
274 }
275 
276 static void filter16_5x5(uint8_t *dstp, int width,
277  float rdiv, float bias, const int *const matrix,
278  const uint8_t *c[], int peak, int radius,
279  int dstride, int stride)
280 {
281  uint16_t *dst = (uint16_t *)dstp;
282  int x;
283 
284  for (x = 0; x < width; x++) {
285  int i, sum = 0;
286 
287  for (i = 0; i < 25; i++)
288  sum += AV_RN16A(&c[i][2 * x]) * matrix[i];
289 
290  sum = (int)(sum * rdiv + bias + 0.5f);
291  dst[x] = av_clip(sum, 0, peak);
292  }
293 }
294 
295 static void filter16_7x7(uint8_t *dstp, int width,
296  float rdiv, float bias, const int *const matrix,
297  const uint8_t *c[], int peak, int radius,
298  int dstride, int stride)
299 {
300  uint16_t *dst = (uint16_t *)dstp;
301  int x;
302 
303  for (x = 0; x < width; x++) {
304  int i, sum = 0;
305 
306  for (i = 0; i < 49; i++)
307  sum += AV_RN16A(&c[i][2 * x]) * matrix[i];
308 
309  sum = (int)(sum * rdiv + bias + 0.5f);
310  dst[x] = av_clip(sum, 0, peak);
311  }
312 }
313 
314 static void filter16_row(uint8_t *dstp, int width,
315  float rdiv, float bias, const int *const matrix,
316  const uint8_t *c[], int peak, int radius,
317  int dstride, int stride)
318 {
319  uint16_t *dst = (uint16_t *)dstp;
320  int x;
321 
322  for (x = 0; x < width; x++) {
323  int i, sum = 0;
324 
325  for (i = 0; i < 2 * radius + 1; i++)
326  sum += AV_RN16A(&c[i][2 * x]) * matrix[i];
327 
328  sum = (int)(sum * rdiv + bias + 0.5f);
329  dst[x] = av_clip(sum, 0, peak);
330  }
331 }
332 
333 static void filter16_column(uint8_t *dstp, int height,
334  float rdiv, float bias, const int *const matrix,
335  const uint8_t *c[], int peak, int radius,
336  int dstride, int stride)
337 {
338  uint16_t *dst = (uint16_t *)dstp;
339  int y;
340 
341  for (y = 0; y < height; y++) {
342  int i, sum = 0;
343 
344  for (i = 0; i < 2 * radius + 1; i++)
345  sum += AV_RN16A(&c[i][0 + y * stride]) * matrix[i];
346 
347  sum = (int)(sum * rdiv + bias + 0.5f);
348  dst[0] = av_clip(sum, 0, peak);
349  dst += dstride / 2;
350  }
351 }
352 
353 static void filter_7x7(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  int x;
359 
360  for (x = 0; x < width; x++) {
361  int i, sum = 0;
362 
363  for (i = 0; i < 49; i++)
364  sum += c[i][x] * matrix[i];
365 
366  sum = (int)(sum * rdiv + bias + 0.5f);
367  dst[x] = av_clip_uint8(sum);
368  }
369 }
370 
371 static void filter_5x5(uint8_t *dst, int width,
372  float rdiv, float bias, const int *const matrix,
373  const uint8_t *c[], int peak, int radius,
374  int dstride, int stride)
375 {
376  int x;
377 
378  for (x = 0; x < width; x++) {
379  int i, sum = 0;
380 
381  for (i = 0; i < 25; i++)
382  sum += c[i][x] * matrix[i];
383 
384  sum = (int)(sum * rdiv + bias + 0.5f);
385  dst[x] = av_clip_uint8(sum);
386  }
387 }
388 
389 static void filter_3x3(uint8_t *dst, int width,
390  float rdiv, float bias, const int *const matrix,
391  const uint8_t *c[], int peak, int radius,
392  int dstride, int stride)
393 {
394  const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
395  const uint8_t *c3 = c[3], *c4 = c[4], *c5 = c[5];
396  const uint8_t *c6 = c[6], *c7 = c[7], *c8 = c[8];
397  int x;
398 
399  for (x = 0; x < width; x++) {
400  int sum = c0[x] * matrix[0] + c1[x] * matrix[1] + c2[x] * matrix[2] +
401  c3[x] * matrix[3] + c4[x] * matrix[4] + c5[x] * matrix[5] +
402  c6[x] * matrix[6] + c7[x] * matrix[7] + c8[x] * matrix[8];
403  sum = (int)(sum * rdiv + bias + 0.5f);
404  dst[x] = av_clip_uint8(sum);
405  }
406 }
407 
408 static void filter_row(uint8_t *dst, int width,
409  float rdiv, float bias, const int *const matrix,
410  const uint8_t *c[], int peak, int radius,
411  int dstride, int stride)
412 {
413  int x;
414 
415  for (x = 0; x < width; x++) {
416  int i, sum = 0;
417 
418  for (i = 0; i < 2 * radius + 1; i++)
419  sum += c[i][x] * matrix[i];
420 
421  sum = (int)(sum * rdiv + bias + 0.5f);
422  dst[x] = av_clip_uint8(sum);
423  }
424 }
425 
426 static void filter_column(uint8_t *dst, int height,
427  float rdiv, float bias, const int *const matrix,
428  const uint8_t *c[], int peak, int radius,
429  int dstride, int stride)
430 {
431  int y;
432 
433  for (y = 0; y < height; y++) {
434  int i, sum = 0;
435 
436  for (i = 0; i < 2 * radius + 1; i++)
437  sum += c[i][0 + y * stride] * matrix[i];
438 
439  sum = (int)(sum * rdiv + bias + 0.5f);
440  dst[0] = av_clip_uint8(sum);
441  dst += dstride;
442  }
443 }
444 
445 static void setup_3x3(int radius, const uint8_t *c[], const uint8_t *src, int stride,
446  int x, int w, int y, int h, int bpc)
447 {
448  int i;
449 
450  for (i = 0; i < 9; i++) {
451  int xoff = FFABS(x + ((i % 3) - 1));
452  int yoff = FFABS(y + (i / 3) - 1);
453 
454  xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
455  yoff = yoff >= h ? 2 * h - 1 - yoff : yoff;
456 
457  c[i] = src + xoff * bpc + yoff * stride;
458  }
459 }
460 
461 static void setup_5x5(int radius, const uint8_t *c[], const uint8_t *src, int stride,
462  int x, int w, int y, int h, int bpc)
463 {
464  int i;
465 
466  for (i = 0; i < 25; i++) {
467  int xoff = FFABS(x + ((i % 5) - 2));
468  int yoff = FFABS(y + (i / 5) - 2);
469 
470  xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
471  yoff = yoff >= h ? 2 * h - 1 - yoff : yoff;
472 
473  c[i] = src + xoff * bpc + yoff * stride;
474  }
475 }
476 
477 static void setup_7x7(int radius, const uint8_t *c[], const uint8_t *src, int stride,
478  int x, int w, int y, int h, int bpc)
479 {
480  int i;
481 
482  for (i = 0; i < 49; i++) {
483  int xoff = FFABS(x + ((i % 7) - 3));
484  int yoff = FFABS(y + (i / 7) - 3);
485 
486  xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
487  yoff = yoff >= h ? 2 * h - 1 - yoff : yoff;
488 
489  c[i] = src + xoff * bpc + yoff * stride;
490  }
491 }
492 
493 static void setup_row(int radius, const uint8_t *c[], const uint8_t *src, int stride,
494  int x, int w, int y, int h, int bpc)
495 {
496  int i;
497 
498  for (i = 0; i < radius * 2 + 1; i++) {
499  int xoff = FFABS(x + i - radius);
500 
501  xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
502 
503  c[i] = src + xoff * bpc + y * stride;
504  }
505 }
506 
507 static void setup_column(int radius, const uint8_t *c[], const uint8_t *src, int stride,
508  int x, int w, int y, int h, int bpc)
509 {
510  int i;
511 
512  for (i = 0; i < radius * 2 + 1; i++) {
513  int xoff = FFABS(x + i - radius);
514 
515  xoff = xoff >= h ? 2 * h - 1 - xoff : xoff;
516 
517  c[i] = src + y * bpc + xoff * stride;
518  }
519 }
520 
521 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
522 {
523  ConvolutionContext *s = ctx->priv;
524  ThreadData *td = arg;
525  AVFrame *in = td->in;
526  AVFrame *out = td->out;
527  int plane;
528 
529  for (plane = 0; plane < s->nb_planes; plane++) {
530  const int mode = s->mode[plane];
531  const int bpc = s->bpc;
532  const int radius = s->size[plane] / 2;
533  const int height = s->planeheight[plane];
534  const int width = s->planewidth[plane];
535  const int stride = in->linesize[plane];
536  const int dstride = out->linesize[plane];
537  const int sizeh = mode == MATRIX_COLUMN ? width : height;
538  const int sizew = mode == MATRIX_COLUMN ? height : width;
539  const int slice_start = (sizeh * jobnr) / nb_jobs;
540  const int slice_end = (sizeh * (jobnr+1)) / nb_jobs;
541  const float rdiv = s->rdiv[plane];
542  const float bias = s->bias[plane];
543  const uint8_t *src = in->data[plane];
544  const int dst_pos = slice_start * (mode == MATRIX_COLUMN ? bpc : dstride);
545  uint8_t *dst = out->data[plane] + dst_pos;
546  const int *matrix = s->matrix[plane];
547  const uint8_t *c[49];
548  int y, x;
549 
550  if (s->copy[plane]) {
551  if (mode == MATRIX_COLUMN)
552  av_image_copy_plane(dst, dstride, src + slice_start * bpc, stride,
553  (slice_end - slice_start) * bpc, height);
554  else
555  av_image_copy_plane(dst, dstride, src + slice_start * stride, stride,
556  width * bpc, slice_end - slice_start);
557  continue;
558  }
559 
560  for (y = slice_start; y < slice_end; y++) {
561  const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : radius * bpc;
562  const int yoff = mode == MATRIX_COLUMN ? radius * stride : 0;
563 
564  for (x = 0; x < radius; x++) {
565  const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc;
566  const int yoff = mode == MATRIX_COLUMN ? x * stride : 0;
567 
568  s->setup[plane](radius, c, src, stride, x, width, y, height, bpc);
569  s->filter[plane](dst + yoff + xoff, 1, rdiv,
570  bias, matrix, c, s->max, radius,
571  dstride, stride);
572  }
573  s->setup[plane](radius, c, src, stride, radius, width, y, height, bpc);
574  s->filter[plane](dst + yoff + xoff, sizew - 2 * radius,
575  rdiv, bias, matrix, c, s->max, radius,
576  dstride, stride);
577  for (x = sizew - radius; x < sizew; x++) {
578  const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc;
579  const int yoff = mode == MATRIX_COLUMN ? x * stride : 0;
580 
581  s->setup[plane](radius, c, src, stride, x, width, y, height, bpc);
582  s->filter[plane](dst + yoff + xoff, 1, rdiv,
583  bias, matrix, c, s->max, radius,
584  dstride, stride);
585  }
586  if (mode != MATRIX_COLUMN)
587  dst += dstride;
588  }
589  }
590 
591  return 0;
592 }
593 
595 {
596  AVFilterContext *ctx = inlink->dst;
597  ConvolutionContext *s = ctx->priv;
599  int p;
600 
601  s->depth = desc->comp[0].depth;
602  s->max = (1 << s->depth) - 1;
603 
604  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
605  s->planewidth[0] = s->planewidth[3] = inlink->w;
606  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
607  s->planeheight[0] = s->planeheight[3] = inlink->h;
608 
609  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
610  s->nb_threads = ff_filter_get_nb_threads(ctx);
611  s->bpc = (s->depth + 7) / 8;
612 
613  if (!strcmp(ctx->filter->name, "convolution")) {
614  if (s->depth > 8) {
615  for (p = 0; p < s->nb_planes; p++) {
616  if (s->mode[p] == MATRIX_ROW)
617  s->filter[p] = filter16_row;
618  else if (s->mode[p] == MATRIX_COLUMN)
619  s->filter[p] = filter16_column;
620  else if (s->size[p] == 3)
621  s->filter[p] = filter16_3x3;
622  else if (s->size[p] == 5)
623  s->filter[p] = filter16_5x5;
624  else if (s->size[p] == 7)
625  s->filter[p] = filter16_7x7;
626  }
627  }
628  } else if (!strcmp(ctx->filter->name, "prewitt")) {
629  if (s->depth > 8)
630  for (p = 0; p < s->nb_planes; p++)
631  s->filter[p] = filter16_prewitt;
632  } else if (!strcmp(ctx->filter->name, "roberts")) {
633  if (s->depth > 8)
634  for (p = 0; p < s->nb_planes; p++)
635  s->filter[p] = filter16_roberts;
636  } else if (!strcmp(ctx->filter->name, "sobel")) {
637  if (s->depth > 8)
638  for (p = 0; p < s->nb_planes; p++)
639  s->filter[p] = filter16_sobel;
640  }
641 
642  return 0;
643 }
644 
646 {
647  AVFilterContext *ctx = inlink->dst;
648  ConvolutionContext *s = ctx->priv;
649  AVFilterLink *outlink = ctx->outputs[0];
650  AVFrame *out;
651  ThreadData td;
652 
653  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
654  if (!out) {
655  av_frame_free(&in);
656  return AVERROR(ENOMEM);
657  }
659 
660  td.in = in;
661  td.out = out;
662  ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN3(s->planeheight[1], s->planewidth[1], s->nb_threads));
663 
664  av_frame_free(&in);
665  return ff_filter_frame(outlink, out);
666 }
667 
669 {
670  ConvolutionContext *s = ctx->priv;
671  int i;
672 
673  if (!strcmp(ctx->filter->name, "convolution")) {
674  for (i = 0; i < 4; i++) {
675  int *matrix = (int *)s->matrix[i];
676  char *p, *arg, *saveptr = NULL;
677  float sum = 0;
678 
679  p = s->matrix_str[i];
680  while (s->matrix_length[i] < 49) {
681  if (!(arg = av_strtok(p, " ", &saveptr)))
682  break;
683 
684  p = NULL;
685  sscanf(arg, "%d", &matrix[s->matrix_length[i]]);
686  sum += matrix[s->matrix_length[i]];
687  s->matrix_length[i]++;
688  }
689 
690  if (!(s->matrix_length[i] & 1)) {
691  av_log(ctx, AV_LOG_ERROR, "number of matrix elements must be odd\n");
692  return AVERROR(EINVAL);
693  }
694  if (s->mode[i] == MATRIX_ROW) {
695  s->filter[i] = filter_row;
696  s->setup[i] = setup_row;
697  s->size[i] = s->matrix_length[i];
698  } else if (s->mode[i] == MATRIX_COLUMN) {
699  s->filter[i] = filter_column;
700  s->setup[i] = setup_column;
701  s->size[i] = s->matrix_length[i];
702  } else if (s->matrix_length[i] == 9) {
703  s->size[i] = 3;
704  if (!memcmp(matrix, same3x3, sizeof(same3x3)))
705  s->copy[i] = 1;
706  else
707  s->filter[i] = filter_3x3;
708  s->setup[i] = setup_3x3;
709  } else if (s->matrix_length[i] == 25) {
710  s->size[i] = 5;
711  if (!memcmp(matrix, same5x5, sizeof(same5x5)))
712  s->copy[i] = 1;
713  else
714  s->filter[i] = filter_5x5;
715  s->setup[i] = setup_5x5;
716  } else if (s->matrix_length[i] == 49) {
717  s->size[i] = 7;
718  if (!memcmp(matrix, same7x7, sizeof(same7x7)))
719  s->copy[i] = 1;
720  else
721  s->filter[i] = filter_7x7;
722  s->setup[i] = setup_7x7;
723  } else {
724  return AVERROR(EINVAL);
725  }
726 
727  if (sum == 0)
728  sum = 1;
729  if (s->rdiv[i] == 0)
730  s->rdiv[i] = 1. / sum;
731 
732  if (s->copy[i] && (s->rdiv[i] != 1. || s->bias[i] != 0.))
733  s->copy[i] = 0;
734  }
735  } else if (!strcmp(ctx->filter->name, "prewitt")) {
736  for (i = 0; i < 4; i++) {
737  if ((1 << i) & s->planes)
738  s->filter[i] = filter_prewitt;
739  else
740  s->copy[i] = 1;
741  s->size[i] = 3;
742  s->setup[i] = setup_3x3;
743  s->rdiv[i] = s->scale;
744  s->bias[i] = s->delta;
745  }
746  } else if (!strcmp(ctx->filter->name, "roberts")) {
747  for (i = 0; i < 4; i++) {
748  if ((1 << i) & s->planes)
749  s->filter[i] = filter_roberts;
750  else
751  s->copy[i] = 1;
752  s->size[i] = 3;
753  s->setup[i] = setup_3x3;
754  s->rdiv[i] = s->scale;
755  s->bias[i] = s->delta;
756  }
757  } else if (!strcmp(ctx->filter->name, "sobel")) {
758  for (i = 0; i < 4; i++) {
759  if ((1 << i) & s->planes)
760  s->filter[i] = filter_sobel;
761  else
762  s->copy[i] = 1;
763  s->size[i] = 3;
764  s->setup[i] = setup_3x3;
765  s->rdiv[i] = s->scale;
766  s->bias[i] = s->delta;
767  }
768  }
769 
770  return 0;
771 }
772 
773 static const AVFilterPad convolution_inputs[] = {
774  {
775  .name = "default",
776  .type = AVMEDIA_TYPE_VIDEO,
777  .config_props = config_input,
778  .filter_frame = filter_frame,
779  },
780  { NULL }
781 };
782 
784  {
785  .name = "default",
786  .type = AVMEDIA_TYPE_VIDEO,
787  },
788  { NULL }
789 };
790 
791 #if CONFIG_CONVOLUTION_FILTER
792 
794  .name = "convolution",
795  .description = NULL_IF_CONFIG_SMALL("Apply convolution filter."),
796  .priv_size = sizeof(ConvolutionContext),
797  .priv_class = &convolution_class,
798  .init = init,
803 };
804 
805 #endif /* CONFIG_CONVOLUTION_FILTER */
806 
807 #if CONFIG_PREWITT_FILTER
808 
809 static const AVOption prewitt_options[] = {
810  { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS},
811  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS},
812  { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS},
813  { NULL }
814 };
815 
816 AVFILTER_DEFINE_CLASS(prewitt);
817 
819  .name = "prewitt",
820  .description = NULL_IF_CONFIG_SMALL("Apply prewitt operator."),
821  .priv_size = sizeof(ConvolutionContext),
822  .priv_class = &prewitt_class,
823  .init = init,
828 };
829 
830 #endif /* CONFIG_PREWITT_FILTER */
831 
832 #if CONFIG_SOBEL_FILTER
833 
834 static const AVOption sobel_options[] = {
835  { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS},
836  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS},
837  { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS},
838  { NULL }
839 };
840 
842 
844  .name = "sobel",
845  .description = NULL_IF_CONFIG_SMALL("Apply sobel operator."),
846  .priv_size = sizeof(ConvolutionContext),
847  .priv_class = &sobel_class,
848  .init = init,
853 };
854 
855 #endif /* CONFIG_SOBEL_FILTER */
856 
857 #if CONFIG_ROBERTS_FILTER
858 
859 static const AVOption roberts_options[] = {
860  { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, FLAGS},
861  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, 0.0, 65535, FLAGS},
862  { "delta", "set delta", OFFSET(delta), AV_OPT_TYPE_FLOAT, {.dbl=0}, -65535, 65535, FLAGS},
863  { NULL }
864 };
865 
866 AVFILTER_DEFINE_CLASS(roberts);
867 
869  .name = "roberts",
870  .description = NULL_IF_CONFIG_SMALL("Apply roberts cross operator."),
871  .priv_size = sizeof(ConvolutionContext),
872  .priv_class = &roberts_class,
873  .init = init,
878 };
879 
880 #endif /* CONFIG_ROBERTS_FILTER */
MATRIX_SQUARE
@ MATRIX_SQUARE
Definition: vf_convolution.c:33
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:99
AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:430
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:409
stride
int stride
Definition: mace.c:144
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
setup_5x5
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)
Definition: vf_convolution.c:461
ConvolutionContext::max
int max
Definition: vf_convolution.c:52
same5x5
static const int same5x5[25]
Definition: vf_convolution.c:102
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
ConvolutionContext::rdiv
float rdiv[4]
Definition: vf_convolution.c:43
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
out
FILE * out
Definition: movenc.c:54
filter_5x5
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)
Definition: vf_convolution.c:371
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
filter_roberts
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)
Definition: vf_convolution.c:218
convolution_inputs
static const AVFilterPad convolution_inputs[]
Definition: vf_convolution.c:773
ConvolutionContext::copy
int copy[4]
Definition: vf_convolution.c:60
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
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_convolution.c:116
OFFSET
#define OFFSET(x)
Definition: vf_convolution.c:70
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
filter16_roberts
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)
Definition: vf_convolution.c:164
AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:422
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
pixdesc.h
AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:429
w
uint8_t w
Definition: llviddspenc.c:38
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:424
AVOption
AVOption.
Definition: opt.h:246
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:387
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:148
c1
static const uint64_t c1
Definition: murmur3.c:49
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:488
ConvolutionContext::matrix
int matrix[4][49]
Definition: vf_convolution.c:58
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1795
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:425
sobel
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)
Definition: vf_edgedetect.c:227
setup_row
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)
Definition: vf_convolution.c:493
AV_PIX_FMT_GRAY9
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:367
av_image_copy_plane
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
formats.h
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2562
AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:421
ConvolutionContext::bias
float bias[4]
Definition: vf_convolution.c:44
filter_column
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)
Definition: vf_convolution.c:426
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:405
dstp
BYTE * dstp
Definition: avisynth_c.h:908
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:403
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:431
plane
int plane
Definition: avisynth_c.h:384
setup_column
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)
Definition: vf_convolution.c:507
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:385
filter16_3x3
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)
Definition: vf_convolution.c:253
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_convolution.c:645
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:371
FFMIN3
#define FFMIN3(a, b, c)
Definition: common.h:97
ConvolutionContext::nb_threads
int nb_threads
Definition: vf_convolution.c:55
src
#define src
Definition: vp8dsp.c:254
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
filter16_sobel
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)
Definition: vf_convolution.c:180
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:390
AV_PIX_FMT_YUVJ411P
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:258
filter16_column
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)
Definition: vf_convolution.c:333
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:84
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:399
ff_set_common_formats
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
ConvolutionContext::planewidth
int planewidth[4]
Definition: vf_convolution.c:56
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:407
width
#define width
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
MatrixMode
MatrixMode
Definition: vf_convolution.c:32
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:408
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:400
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2026
MATRIX_ROW
@ MATRIX_ROW
Definition: vf_convolution.c:34
av_strtok
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
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(convolution)
ConvolutionContext::planeheight
int planeheight[4]
Definition: vf_convolution.c:57
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:384
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:398
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:370
ConvolutionContext::filter
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: vf_convolution.c:64
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
f
#define f(width, name)
Definition: cbs_vp9.c:255
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
arg
const char * arg
Definition: jacosubdec.c:66
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:368
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_convolution.c:668
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:406
filter_sobel
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)
Definition: vf_convolution.c:233
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
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:654
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
ConvolutionContext::matrix_str
char * matrix_str[4]
Definition: vf_convolution.c:42
MATRIX_COLUMN
@ MATRIX_COLUMN
Definition: vf_convolution.c:35
ConvolutionContext::depth
int depth
Definition: vf_convolution.c:51
ConvolutionContext
Definition: vf_convolution.c:39
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:388
inputs
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
Definition: filter_design.txt:243
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
AV_PIX_FMT_GBRP9
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:402
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
ConvolutionContext::scale
float scale
Definition: vf_convolution.c:46
desc
const char * desc
Definition: nvenc.c:68
planes
static const struct @314 planes[]
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:188
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:392
MATRIX_NBMODES
@ MATRIX_NBMODES
Definition: vf_convolution.c:36
ff_vf_convolution
AVFilter ff_vf_convolution
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:394
height
#define height
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:426
filter16_row
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)
Definition: vf_convolution.c:314
internal.h
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#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
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:226
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;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);return NULL;} return ac;} 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;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->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);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
filter_slice
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_convolution.c:521
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
ConvolutionContext::nb_planes
int nb_planes
Definition: vf_convolution.c:54
setup_7x7
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)
Definition: vf_convolution.c:477
ConvolutionContext::size
int size[4]
Definition: vf_convolution.c:50
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:404
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
ff_vf_sobel
AVFilter ff_vf_sobel
ff_vf_prewitt
AVFilter ff_vf_prewitt
delta
float delta
Definition: vorbis_enc_data.h:457
ThreadData
Used for passing data between threads.
Definition: af_adeclick.c:487
setup_3x3
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)
Definition: vf_convolution.c:445
AV_PIX_FMT_YUVJ440P
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition: pixfmt.h:100
uint8_t
uint8_t
Definition: audio_convert.c:194
filter16_7x7
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)
Definition: vf_convolution.c:295
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
ConvolutionContext::bpc
int bpc
Definition: vf_convolution.c:53
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:386
convolution_options
static const AVOption convolution_options[]
Definition: vf_convolution.c:73
AVFilter
Filter definition.
Definition: avfilter.h:144
AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:423
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:391
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:396
convolution_outputs
static const AVFilterPad convolution_outputs[]
Definition: vf_convolution.c:783
c2
static const uint64_t c2
Definition: murmur3.c:50
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
AV_RN16A
#define AV_RN16A(p)
Definition: intreadwrite.h:522
ConvolutionContext::setup
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: vf_convolution.c:62
ff_vf_roberts
AVFilter ff_vf_roberts
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
AVFilterContext
An instance of a filter.
Definition: avfilter.h:338
filter16_prewitt
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)
Definition: vf_convolution.c:146
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
ConvolutionContext::delta
float delta
Definition: vf_convolution.c:47
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:116
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
filter_7x7
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)
Definition: vf_convolution.c:353
ThreadData::in
AVFrame * in
Definition: af_afftdn.c:1082
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
filter_row
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)
Definition: vf_convolution.c:408
same3x3
static const int same3x3[9]
Definition: vf_convolution.c:98
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_convolution.c:594
filter16_5x5
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)
Definition: vf_convolution.c:276
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
same7x7
static const int same7x7[49]
Definition: vf_convolution.c:108
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:393
h
h
Definition: vp9dsp_template.c:2038
ConvolutionContext::matrix_length
int matrix_length[4]
Definition: vf_convolution.c:59
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:397
filter_3x3
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)
Definition: vf_convolution.c:389
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:227
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:369
FLAGS
#define FLAGS
Definition: vf_convolution.c:71
int
int
Definition: ffmpeg_filter.c:191
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:395
ConvolutionContext::planes
int planes
Definition: vf_convolution.c:48
filter_prewitt
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)
Definition: vf_convolution.c:198