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 
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 
573  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
574  s->nb_threads = ff_filter_get_nb_threads(ctx);
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  }
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,
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,
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,
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,
845 };
846 
847 #endif /* CONFIG_ROBERTS_FILTER */
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:440
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:419
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:425
same5x5
static const int same5x5[25]
Definition: vf_convolution.c:65
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
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:300
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:335
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2549
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:182
convolution_inputs
static const AVFilterPad convolution_inputs[]
Definition: vf_convolution.c:740
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:79
OFFSET
#define OFFSET(x)
Definition: vf_convolution.c:33
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
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:128
AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:432
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
pixdesc.h
AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:439
w
uint8_t w
Definition: llviddspenc.c:38
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:434
AVOption
AVOption.
Definition: opt.h:246
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:397
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:494
convolution.h
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1788
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:435
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:229
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:457
AV_PIX_FMT_GRAY9
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:377
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:2589
AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:431
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:390
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:415
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:413
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:441
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:471
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:395
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:217
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_convolution.c:612
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:381
FFMIN3
#define FFMIN3(a, b, c)
Definition: common.h:97
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:144
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:400
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:297
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:90
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:409
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:605
MATRIX_NBMODES
@ MATRIX_NBMODES
Definition: convolution.h:29
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:417
width
#define width
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
MATRIX_SQUARE
@ MATRIX_SQUARE
Definition: convolution.h:26
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:418
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:410
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:2040
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)
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:438
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:394
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:408
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:380
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:378
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_convolution.c:635
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:416
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:197
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:659
MATRIX_ROW
@ MATRIX_ROW
Definition: convolution.h:27
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
src
#define src
Definition: vp8dsp.c:254
ConvolutionContext
Definition: convolution.h:32
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:398
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:412
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
desc
const char * desc
Definition: nvenc.c:79
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:402
ff_vf_convolution
AVFilter ff_vf_convolution
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:404
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:436
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:278
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
planes
static const struct @315 planes[]
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:485
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
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:441
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:414
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:784
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: dsddec.c:67
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:409
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:259
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:396
convolution_options
static const AVOption convolution_options[]
Definition: vf_convolution.c:36
AVFilter
Filter definition.
Definition: avfilter.h:144
AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:433
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:401
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:406
convolution_outputs
static const AVFilterPad convolution_outputs[]
Definition: vf_convolution.c:750
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_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:437
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
AV_RN16A
#define AV_RN16A(p)
Definition: intreadwrite.h:522
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:110
MATRIX_COLUMN
@ MATRIX_COLUMN
Definition: convolution.h:28
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
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:317
ThreadData::in
AVFrame * in
Definition: af_afftdn.c:1083
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:372
ff_convolution_init_x86
void ff_convolution_init_x86(ConvolutionContext *s)
Definition: vf_convolution_init.c:32
same3x3
static const int same3x3[9]
Definition: vf_convolution.c:61
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_convolution.c:558
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:240
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:71
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:403
h
h
Definition: vp9dsp_template.c:2038
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:407
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:353
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:379
FLAGS
#define FLAGS
Definition: vf_convolution.c:34
int
int
Definition: ffmpeg_filter.c:192
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:405
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:162