FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 
139  return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
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(sqrt(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(sqrt(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(sqrt(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(sqrt(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(sqrt(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(sqrt(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 
594 static int config_input(AVFilterLink *inlink)
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 
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 
645 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
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  }
658  av_frame_copy_props(out, in);
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,
800  .inputs = convolution_inputs,
801  .outputs = convolution_outputs,
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,
825  .inputs = convolution_inputs,
826  .outputs = convolution_outputs,
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,
850  .inputs = convolution_inputs,
851  .outputs = convolution_outputs,
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,
875  .inputs = convolution_inputs,
876  .outputs = convolution_outputs,
878 };
879 
880 #endif /* CONFIG_ROBERTS_FILTER */
int plane
Definition: avisynth_c.h:422
#define NULL
Definition: coverity.c:32
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:420
AVFrame * out
Definition: af_adeclick.c:485
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:414
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2406
This structure describes decoded (raw) audio or video data.
Definition: frame.h:218
AVOption.
Definition: opt.h:246
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:416
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:389
static void filter16_sobel(uint8_t *dstp, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:399
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:417
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2446
Main libavfilter public API header.
static void sobel(int w, int h, uint16_t *dst, int dst_linesize, int8_t *dir, int dir_linesize, const uint8_t *src, int src_linesize)
const char * desc
Definition: nvenc.c:65
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:395
static void filter16_column(uint8_t *dstp, int height, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
AVFilter ff_vf_prewitt
static void setup_7x7(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:359
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:383
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
#define src
Definition: vp8dsp.c:254
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:360
static void filter16_row(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:125
const char * name
Pad name.
Definition: internal.h:60
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:361
static void setup_5x5(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
static void filter_7x7(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
AVFrame * in
Definition: af_aiir.c:33
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:82
static void filter_5x5(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
float delta
AVOptions.
#define f(width, name)
Definition: cbs_vp9.c:255
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:413
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:394
#define height
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:100
static const struct @283 planes[]
#define FFMIN3(a, b, c)
Definition: common.h:97
static const uint64_t c1
Definition: murmur3.c:49
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
void(* setup[4])(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int width, int y, int height, int bpc)
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:392
ptrdiff_t size
Definition: opengl_enc.c:101
#define flags(name, subs,...)
Definition: cbs_h2645.c:263
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:384
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:419
#define av_log(a,...)
AVFilter ff_vf_convolution
A filter pad used for either input or output.
Definition: internal.h:54
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:568
#define td
Definition: regdef.h:70
static const int same7x7[49]
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
AVFilter ff_vf_sobel
BYTE * dstp
Definition: avisynth_c.h:813
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static const AVFilterPad convolution_inputs[]
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:421
const char * arg
Definition: jacosubdec.c:66
uint16_t width
Definition: gdv.c:47
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:400
static void filter_row(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:382
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:401
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:377
static void filter16_prewitt(uint8_t *dstp, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:398
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:363
static const AVFilterPad convolution_outputs[]
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
static void filter16_3x3(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
uint8_t w
Definition: llviddspenc.c:38
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
static const AVOption convolution_options[]
AVFormatContext * ctx
Definition: movenc.c:48
static int query_formats(AVFilterContext *ctx)
static av_cold int init(AVFilterContext *ctx)
static void filter_prewitt(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
#define s(width, name)
Definition: cbs_vp9.c:257
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:418
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:378
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:397
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:390
static void filter_roberts(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:387
Used for passing data between threads.
Definition: af_adeclick.c:484
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:249
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
AVFilter ff_vf_roberts
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
static void filter_column(uint8_t *dst, int height, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:379
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
MatrixMode
static void setup_3x3(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
AVFILTER_DEFINE_CLASS(convolution)
static const int same3x3[9]
static void setup_row(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
const char * name
Filter name.
Definition: avfilter.h:148
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:385
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:376
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:266
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:388
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:396
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:380
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:386
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
Definition: avstring.c:184
static void filter_sobel(uint8_t *dst, int width, float scale, float delta, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
static void setup_column(int radius, const uint8_t *c[], const uint8_t *src, int stride, int x, int w, int y, int h, int bpc)
int
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:105
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
Y , 8bpp.
Definition: pixfmt.h:74
static void filter16_5x5(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
static double c[64]
static const int same5x5[25]
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:415
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
static const uint64_t c2
Definition: murmur3.c:50
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
avfilter_execute_func * execute
Definition: internal.h:155
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2029
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)
static void filter16_7x7(uint8_t *dstp, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:258
static void filter_3x3(uint8_t *dst, int width, float rdiv, float bias, const int *const matrix, const uint8_t *c[], int peak, int radius, int dstride, int stride)
#define AV_RN16A(p)
Definition: intreadwrite.h:522
static int config_input(AVFilterLink *inlink)
#define FLAGS
An instance of a filter.
Definition: avfilter.h:338
#define OFFSET(x)
FILE * out
Definition: movenc.c:54
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:338
#define stride
internal API functions
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)
int depth
Number of bits in the component.
Definition: pixdesc.h:58
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
mode
Use these values in ebur128_init (or'ed).
Definition: ebur128.h:83
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:341
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:391
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:652
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58