FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vf_waveform.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2015 Paul B Mahol
3  * Copyright (c) 2013 Marton Balint
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/avassert.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/parseutils.h"
25 #include "libavutil/pixdesc.h"
26 #include "avfilter.h"
27 #include "formats.h"
28 #include "internal.h"
29 #include "video.h"
30 
31 enum FilterType {
39 };
40 
41 typedef struct WaveformContext {
42  const AVClass *class;
43  int mode;
44  int ncomp;
45  int pcomp;
46  const uint8_t *bg_color;
47  float fintensity;
48  int intensity;
49  int mirror;
50  int display;
51  int envelope;
52  int estart[4];
53  int eend[4];
54  int *emax[4][4];
55  int *emin[4][4];
56  int *peak;
57  int filter;
58  int bits;
59  int max;
60  int size;
62  int component, int intensity, int offset, int column);
65 
66 #define OFFSET(x) offsetof(WaveformContext, x)
67 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
68 
69 static const AVOption waveform_options[] = {
70  { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "mode" },
71  { "m", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "mode" },
72  { "row", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" },
73  { "column", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" },
74  { "intensity", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 1, FLAGS },
75  { "i", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 1, FLAGS },
76  { "mirror", "set mirroring", OFFSET(mirror), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
77  { "r", "set mirroring", OFFSET(mirror), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
78  { "display", "set display mode", OFFSET(display), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "display" },
79  { "d", "set display mode", OFFSET(display), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "display" },
80  { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "display" },
81  { "parade", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "display" },
82  { "components", "set components to display", OFFSET(pcomp), AV_OPT_TYPE_INT, {.i64=1}, 1, 15, FLAGS },
83  { "c", "set components to display", OFFSET(pcomp), AV_OPT_TYPE_INT, {.i64=1}, 1, 15, FLAGS },
84  { "envelope", "set envelope to display", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "envelope" },
85  { "e", "set envelope to display", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "envelope" },
86  { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "envelope" },
87  { "instant", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "envelope" },
88  { "peak", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "envelope" },
89  { "peak+instant", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "envelope" },
90  { "filter", "set filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FILTERS-1, FLAGS, "filter" },
91  { "f", "set filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FILTERS-1, FLAGS, "filter" },
92  { "lowpass", NULL, 0, AV_OPT_TYPE_CONST, {.i64=LOWPASS}, 0, 0, FLAGS, "filter" },
93  { "flat" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=FLAT}, 0, 0, FLAGS, "filter" },
94  { "aflat" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=AFLAT}, 0, 0, FLAGS, "filter" },
95  { "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=CHROMA}, 0, 0, FLAGS, "filter" },
96  { "achroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ACHROMA}, 0, 0, FLAGS, "filter" },
97  { "color", NULL, 0, AV_OPT_TYPE_CONST, {.i64=COLOR}, 0, 0, FLAGS, "filter" },
98  { NULL }
99 };
100 
102 
103 static const enum AVPixelFormat lowpass_pix_fmts[] = {
118 };
119 
120 static const enum AVPixelFormat flat_pix_fmts[] = {
122 };
123 
124 static const enum AVPixelFormat color_pix_fmts[] = {
130 };
131 
133 {
134  WaveformContext *s = ctx->priv;
135  AVFilterFormats *fmts_list;
136  const enum AVPixelFormat *pix_fmts;
137 
138  switch (s->filter) {
139  case LOWPASS: pix_fmts = lowpass_pix_fmts; break;
140  case FLAT:
141  case AFLAT:
142  case CHROMA:
143  case ACHROMA: pix_fmts = flat_pix_fmts; break;
144  case COLOR: pix_fmts = color_pix_fmts; break;
145  }
146 
147  fmts_list = ff_make_format_list(pix_fmts);
148  if (!fmts_list)
149  return AVERROR(ENOMEM);
150  return ff_set_common_formats(ctx, fmts_list);
151 }
152 
153 static void envelope_instant16(WaveformContext *s, AVFrame *out, int plane, int component)
154 {
155  const int dst_linesize = out->linesize[component] / 2;
156  const int bg = s->bg_color[component] * (s->max / 256);
157  const int limit = s->max - 1;
158  const int is_chroma = (component == 1 || component == 2);
159  const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0);
160  const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0);
161  const int dst_h = FF_CEIL_RSHIFT(out->height, shift_h);
162  const int dst_w = FF_CEIL_RSHIFT(out->width, shift_w);
163  const int start = s->estart[plane];
164  const int end = s->eend[plane];
165  uint16_t *dst;
166  int x, y;
167 
168  if (s->mode) {
169  for (x = 0; x < dst_w; x++) {
170  for (y = start; y < end; y++) {
171  dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
172  if (dst[0] != bg) {
173  dst[0] = limit;
174  break;
175  }
176  }
177  for (y = end - 1; y >= start; y--) {
178  dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
179  if (dst[0] != bg) {
180  dst[0] = limit;
181  break;
182  }
183  }
184  }
185  } else {
186  for (y = 0; y < dst_h; y++) {
187  dst = (uint16_t *)out->data[component] + y * dst_linesize;
188  for (x = start; x < end; x++) {
189  if (dst[x] != bg) {
190  dst[x] = limit;
191  break;
192  }
193  }
194  for (x = end - 1; x >= start; x--) {
195  if (dst[x] != bg) {
196  dst[x] = limit;
197  break;
198  }
199  }
200  }
201  }
202 }
203 
204 static void envelope_instant(WaveformContext *s, AVFrame *out, int plane, int component)
205 {
206  const int dst_linesize = out->linesize[component];
207  const uint8_t bg = s->bg_color[component];
208  const int is_chroma = (component == 1 || component == 2);
209  const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0);
210  const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0);
211  const int dst_h = FF_CEIL_RSHIFT(out->height, shift_h);
212  const int dst_w = FF_CEIL_RSHIFT(out->width, shift_w);
213  const int start = s->estart[plane];
214  const int end = s->eend[plane];
215  uint8_t *dst;
216  int x, y;
217 
218  if (s->mode) {
219  for (x = 0; x < dst_w; x++) {
220  for (y = start; y < end; y++) {
221  dst = out->data[component] + y * dst_linesize + x;
222  if (dst[0] != bg) {
223  dst[0] = 255;
224  break;
225  }
226  }
227  for (y = end - 1; y >= start; y--) {
228  dst = out->data[component] + y * dst_linesize + x;
229  if (dst[0] != bg) {
230  dst[0] = 255;
231  break;
232  }
233  }
234  }
235  } else {
236  for (y = 0; y < dst_h; y++) {
237  dst = out->data[component] + y * dst_linesize;
238  for (x = start; x < end; x++) {
239  if (dst[x] != bg) {
240  dst[x] = 255;
241  break;
242  }
243  }
244  for (x = end - 1; x >= start; x--) {
245  if (dst[x] != bg) {
246  dst[x] = 255;
247  break;
248  }
249  }
250  }
251  }
252 }
253 
254 static void envelope_peak16(WaveformContext *s, AVFrame *out, int plane, int component)
255 {
256  const int dst_linesize = out->linesize[component] / 2;
257  const int bg = s->bg_color[component] * (s->max / 256);
258  const int limit = s->max - 1;
259  const int is_chroma = (component == 1 || component == 2);
260  const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0);
261  const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0);
262  const int dst_h = FF_CEIL_RSHIFT(out->height, shift_h);
263  const int dst_w = FF_CEIL_RSHIFT(out->width, shift_w);
264  const int start = s->estart[plane];
265  const int end = s->eend[plane];
266  int *emax = s->emax[plane][component];
267  int *emin = s->emin[plane][component];
268  uint16_t *dst;
269  int x, y;
270 
271  if (s->mode) {
272  for (x = 0; x < dst_w; x++) {
273  for (y = start; y < end && y < emin[x]; y++) {
274  dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
275  if (dst[0] != bg) {
276  emin[x] = y;
277  break;
278  }
279  }
280  for (y = end - 1; y >= start && y >= emax[x]; y--) {
281  dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
282  if (dst[0] != bg) {
283  emax[x] = y;
284  break;
285  }
286  }
287  }
288 
289  if (s->envelope == 3)
290  envelope_instant16(s, out, plane, component);
291 
292  for (x = 0; x < dst_w; x++) {
293  dst = (uint16_t *)out->data[component] + emin[x] * dst_linesize + x;
294  dst[0] = limit;
295  dst = (uint16_t *)out->data[component] + emax[x] * dst_linesize + x;
296  dst[0] = limit;
297  }
298  } else {
299  for (y = 0; y < dst_h; y++) {
300  dst = (uint16_t *)out->data[component] + y * dst_linesize;
301  for (x = start; x < end && x < emin[y]; x++) {
302  if (dst[x] != bg) {
303  emin[y] = x;
304  break;
305  }
306  }
307  for (x = end - 1; x >= start && x >= emax[y]; x--) {
308  if (dst[x] != bg) {
309  emax[y] = x;
310  break;
311  }
312  }
313  }
314 
315  if (s->envelope == 3)
316  envelope_instant16(s, out, plane, component);
317 
318  for (y = 0; y < dst_h; y++) {
319  dst = (uint16_t *)out->data[component] + y * dst_linesize + emin[y];
320  dst[0] = limit;
321  dst = (uint16_t *)out->data[component] + y * dst_linesize + emax[y];
322  dst[0] = limit;
323  }
324  }
325 }
326 
327 static void envelope_peak(WaveformContext *s, AVFrame *out, int plane, int component)
328 {
329  const int dst_linesize = out->linesize[component];
330  const int bg = s->bg_color[component];
331  const int is_chroma = (component == 1 || component == 2);
332  const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0);
333  const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0);
334  const int dst_h = FF_CEIL_RSHIFT(out->height, shift_h);
335  const int dst_w = FF_CEIL_RSHIFT(out->width, shift_w);
336  const int start = s->estart[plane];
337  const int end = s->eend[plane];
338  int *emax = s->emax[plane][component];
339  int *emin = s->emin[plane][component];
340  uint8_t *dst;
341  int x, y;
342 
343  if (s->mode) {
344  for (x = 0; x < dst_w; x++) {
345  for (y = start; y < end && y < emin[x]; y++) {
346  dst = out->data[component] + y * dst_linesize + x;
347  if (dst[0] != bg) {
348  emin[x] = y;
349  break;
350  }
351  }
352  for (y = end - 1; y >= start && y >= emax[x]; y--) {
353  dst = out->data[component] + y * dst_linesize + x;
354  if (dst[0] != bg) {
355  emax[x] = y;
356  break;
357  }
358  }
359  }
360 
361  if (s->envelope == 3)
362  envelope_instant(s, out, plane, component);
363 
364  for (x = 0; x < dst_w; x++) {
365  dst = out->data[component] + emin[x] * dst_linesize + x;
366  dst[0] = 255;
367  dst = out->data[component] + emax[x] * dst_linesize + x;
368  dst[0] = 255;
369  }
370  } else {
371  for (y = 0; y < dst_h; y++) {
372  dst = out->data[component] + y * dst_linesize;
373  for (x = start; x < end && x < emin[y]; x++) {
374  if (dst[x] != bg) {
375  emin[y] = x;
376  break;
377  }
378  }
379  for (x = end - 1; x >= start && x >= emax[y]; x--) {
380  if (dst[x] != bg) {
381  emax[y] = x;
382  break;
383  }
384  }
385  }
386 
387  if (s->envelope == 3)
388  envelope_instant(s, out, plane, component);
389 
390  for (y = 0; y < dst_h; y++) {
391  dst = out->data[component] + y * dst_linesize + emin[y];
392  dst[0] = 255;
393  dst = out->data[component] + y * dst_linesize + emax[y];
394  dst[0] = 255;
395  }
396  }
397 }
398 
399 static void envelope16(WaveformContext *s, AVFrame *out, int plane, int component)
400 {
401  if (s->envelope == 0) {
402  return;
403  } else if (s->envelope == 1) {
404  envelope_instant16(s, out, plane, component);
405  } else {
406  envelope_peak16(s, out, plane, component);
407  }
408 }
409 
410 static void envelope(WaveformContext *s, AVFrame *out, int plane, int component)
411 {
412  if (s->envelope == 0) {
413  return;
414  } else if (s->envelope == 1) {
415  envelope_instant(s, out, plane, component);
416  } else {
417  envelope_peak(s, out, plane, component);
418  }
419 }
420 
421 static void update16(uint16_t *target, int max, int intensity, int limit)
422 {
423  if (*target <= max)
424  *target += intensity;
425  else
426  *target = limit;
427 }
428 
429 static void update(uint8_t *target, int max, int intensity)
430 {
431  if (*target <= max)
432  *target += intensity;
433  else
434  *target = 255;
435 }
436 
438  int component, int intensity, int offset, int column)
439 {
440  const int plane = s->desc->comp[component].plane;
441  const int mirror = s->mirror;
442  const int is_chroma = (component == 1 || component == 2);
443  const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0);
444  const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0);
445  const int src_linesize = in->linesize[plane] / 2;
446  const int dst_linesize = out->linesize[plane] / 2;
447  const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
448  const int limit = s->max - 1;
449  const int max = limit - intensity;
450  const int src_h = FF_CEIL_RSHIFT(in->height, shift_h);
451  const int src_w = FF_CEIL_RSHIFT(in->width, shift_w);
452  const uint16_t *src_data = (const uint16_t *)in->data[plane];
453  uint16_t *dst_data = (uint16_t *)out->data[plane] + (column ? (offset >> shift_h) * dst_linesize : offset >> shift_w);
454  uint16_t * const dst_bottom_line = dst_data + dst_linesize * ((s->size >> shift_h) - 1);
455  uint16_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
456  const uint16_t *p;
457  int y;
458 
459  if (!column && mirror)
460  dst_data += s->size >> shift_w;
461 
462  for (y = 0; y < src_h; y++) {
463  const uint16_t *src_data_end = src_data + src_w;
464  uint16_t *dst = dst_line;
465 
466  for (p = src_data; p < src_data_end; p++) {
467  uint16_t *target;
468  int v = FFMIN(*p, limit);
469 
470  if (column) {
471  target = dst++ + dst_signed_linesize * (v >> shift_h);
472  } else {
473  if (mirror)
474  target = dst_data - (v >> shift_w) - 1;
475  else
476  target = dst_data + (v >> shift_w);
477  }
478  update16(target, max, intensity, limit);
479  }
480  src_data += src_linesize;
481  dst_data += dst_linesize;
482  }
483 
484  envelope16(s, out, plane, plane);
485 }
486 
488  int component, int intensity, int offset, int column)
489 {
490  const int plane = s->desc->comp[component].plane;
491  const int mirror = s->mirror;
492  const int is_chroma = (component == 1 || component == 2);
493  const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0);
494  const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0);
495  const int src_linesize = in->linesize[plane];
496  const int dst_linesize = out->linesize[plane];
497  const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
498  const int max = 255 - intensity;
499  const int src_h = FF_CEIL_RSHIFT(in->height, shift_h);
500  const int src_w = FF_CEIL_RSHIFT(in->width, shift_w);
501  const uint8_t *src_data = in->data[plane];
502  uint8_t *dst_data = out->data[plane] + (column ? (offset >> shift_h) * dst_linesize : offset >> shift_w);
503  uint8_t * const dst_bottom_line = dst_data + dst_linesize * ((s->size >> shift_h) - 1);
504  uint8_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
505  const uint8_t *p;
506  int y;
507 
508  if (!column && mirror)
509  dst_data += s->size >> shift_w;
510 
511  for (y = 0; y < src_h; y++) {
512  const uint8_t *src_data_end = src_data + src_w;
513  uint8_t *dst = dst_line;
514 
515  for (p = src_data; p < src_data_end; p++) {
516  uint8_t *target;
517  if (column) {
518  target = dst++ + dst_signed_linesize * (*p >> shift_h);
519  } else {
520  if (mirror)
521  target = dst_data - (*p >> shift_w) - 1;
522  else
523  target = dst_data + (*p >> shift_w);
524  }
525  update(target, max, intensity);
526  }
527  src_data += src_linesize;
528  dst_data += dst_linesize;
529  }
530 
531  envelope(s, out, plane, plane);
532 }
533 
535  int component, int intensity, int offset, int column)
536 {
537  const int plane = s->desc->comp[component].plane;
538  const int mirror = s->mirror;
539  const int c0_linesize = in->linesize[ plane + 0 ];
540  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
541  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
542  const int d0_linesize = out->linesize[ plane + 0 ];
543  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
544  const int max = 255 - intensity;
545  const int src_h = in->height;
546  const int src_w = in->width;
547  int x, y;
548 
549  if (column) {
550  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
551  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
552 
553  for (x = 0; x < src_w; x++) {
554  const uint8_t *c0_data = in->data[plane + 0];
555  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
556  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
557  uint8_t *d0_data = out->data[plane] + offset * d0_linesize;
558  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset * d1_linesize;
559  uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
560  uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
561  uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
562  uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
563 
564  for (y = 0; y < src_h; y++) {
565  const int c0 = c0_data[x] + 256;
566  const int c1 = FFABS(c1_data[x] - 128) + FFABS(c2_data[x] - 128);
567  uint8_t *target;
568  int p;
569 
570  target = d0 + x + d0_signed_linesize * c0;
571  update(target, max, intensity);
572 
573  for (p = c0 - c1; p < c0 + c1; p++) {
574  target = d1 + x + d1_signed_linesize * p;
575  update(target, max, 1);
576  }
577  c0_data += c0_linesize;
578  c1_data += c1_linesize;
579  c2_data += c2_linesize;
580  d0_data += d0_linesize;
581  d1_data += d1_linesize;
582  }
583  }
584  } else {
585  const uint8_t *c0_data = in->data[plane];
586  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
587  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
588  uint8_t *d0_data = out->data[plane] + offset;
589  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset;
590 
591  if (mirror) {
592  d0_data += s->size - 1;
593  d1_data += s->size - 1;
594  }
595 
596  for (y = 0; y < src_h; y++) {
597  for (x = 0; x < src_w; x++) {
598  int c0 = c0_data[x] + 256;
599  const int c1 = FFABS(c1_data[x] - 128) + FFABS(c2_data[x] - 128);
600  uint8_t *target;
601  int p;
602 
603  if (mirror)
604  target = d0_data - c0;
605  else
606  target = d0_data + c0;
607 
608  update(target, max, intensity);
609 
610  for (p = c0 - c1; p < c0 + c1; p++) {
611  if (mirror)
612  target = d1_data - p;
613  else
614  target = d1_data + p;
615 
616  update(target, max, 1);
617  }
618  }
619 
620  c0_data += c0_linesize;
621  c1_data += c1_linesize;
622  c2_data += c2_linesize;
623  d0_data += d0_linesize;
624  d1_data += d1_linesize;
625  }
626  }
627 
628  envelope(s, out, plane, plane);
629  envelope(s, out, plane, (plane + 1) % s->ncomp);
630 }
631 
633  int component, int intensity, int offset, int column)
634 {
635  const int plane = s->desc->comp[component].plane;
636  const int mirror = s->mirror;
637  const int c0_linesize = in->linesize[ plane + 0 ];
638  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
639  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
640  const int d0_linesize = out->linesize[ plane + 0 ];
641  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
642  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp];
643  const int max = 255 - intensity;
644  const int src_h = in->height;
645  const int src_w = in->width;
646  int x, y;
647 
648  if (column) {
649  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
650  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
651  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
652 
653  for (x = 0; x < src_w; x++) {
654  const uint8_t *c0_data = in->data[plane + 0];
655  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
656  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
657  uint8_t *d0_data = out->data[plane] + offset * d0_linesize;
658  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset * d1_linesize;
659  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset * d2_linesize;
660  uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
661  uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
662  uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
663  uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
664  uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
665  uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data);
666 
667  for (y = 0; y < src_h; y++) {
668  const int c0 = c0_data[x] + 128;
669  const int c1 = c1_data[x] - 128;
670  const int c2 = c2_data[x] - 128;
671  uint8_t *target;
672  int p;
673 
674  target = d0 + x + d0_signed_linesize * c0;
675  update(target, max, intensity);
676 
677  for (p = c0 + c1; p < c0; p++) {
678  target = d1 + x + d1_signed_linesize * p;
679  update(target, max, 1);
680  }
681 
682  for (p = c0 + c1 - 1; p > c0; p--) {
683  target = d1 + x + d1_signed_linesize * p;
684  update(target, max, 1);
685  }
686 
687  for (p = c0 + c2; p < c0; p++) {
688  target = d2 + x + d2_signed_linesize * p;
689  update(target, max, 1);
690  }
691 
692  for (p = c0 + c2 - 1; p > c0; p--) {
693  target = d2 + x + d2_signed_linesize * p;
694  update(target, max, 1);
695  }
696 
697  c0_data += c0_linesize;
698  c1_data += c1_linesize;
699  c2_data += c2_linesize;
700  d0_data += d0_linesize;
701  d1_data += d1_linesize;
702  d2_data += d2_linesize;
703  }
704  }
705  } else {
706  const uint8_t *c0_data = in->data[plane];
707  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
708  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
709  uint8_t *d0_data = out->data[plane] + offset;
710  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset;
711  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset;
712 
713  if (mirror) {
714  d0_data += s->size - 1;
715  d1_data += s->size - 1;
716  d2_data += s->size - 1;
717  }
718 
719  for (y = 0; y < src_h; y++) {
720  for (x = 0; x < src_w; x++) {
721  const int c0 = c0_data[x] + 128;
722  const int c1 = c1_data[x] - 128;
723  const int c2 = c2_data[x] - 128;
724  uint8_t *target;
725  int p;
726 
727  if (mirror)
728  target = d0_data - c0;
729  else
730  target = d0_data + c0;
731 
732  update(target, max, intensity);
733 
734  for (p = c0 + c1; p < c0; p++) {
735  if (mirror)
736  target = d1_data - p;
737  else
738  target = d1_data + p;
739 
740  update(target, max, 1);
741  }
742 
743  for (p = c0 + 1; p < c0 + c1; p++) {
744  if (mirror)
745  target = d1_data - p;
746  else
747  target = d1_data + p;
748 
749  update(target, max, 1);
750  }
751 
752  for (p = c0 + c2; p < c0; p++) {
753  if (mirror)
754  target = d2_data - p;
755  else
756  target = d2_data + p;
757 
758  update(target, max, 1);
759  }
760 
761  for (p = c0 + 1; p < c0 + c2; p++) {
762  if (mirror)
763  target = d2_data - p;
764  else
765  target = d2_data + p;
766 
767  update(target, max, 1);
768  }
769  }
770 
771  c0_data += c0_linesize;
772  c1_data += c1_linesize;
773  c2_data += c2_linesize;
774  d0_data += d0_linesize;
775  d1_data += d1_linesize;
776  d2_data += d2_linesize;
777  }
778  }
779 
780  envelope(s, out, plane, (plane + 0) % s->ncomp);
781  envelope(s, out, plane, (plane + 1) % s->ncomp);
782  envelope(s, out, plane, (plane + 2) % s->ncomp);
783 }
784 
786  int component, int intensity, int offset, int column)
787 {
788  const int plane = s->desc->comp[component].plane;
789  const int mirror = s->mirror;
790  const int c0_linesize = in->linesize[(plane + 1) % s->ncomp];
791  const int c1_linesize = in->linesize[(plane + 2) % s->ncomp];
792  const int dst_linesize = out->linesize[plane];
793  const int max = 255 - intensity;
794  const int src_h = in->height;
795  const int src_w = in->width;
796  int x, y;
797 
798  if (column) {
799  const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
800 
801  for (x = 0; x < src_w; x++) {
802  const uint8_t *c0_data = in->data[(plane + 1) % s->ncomp];
803  const uint8_t *c1_data = in->data[(plane + 2) % s->ncomp];
804  uint8_t *dst_data = out->data[plane] + offset * dst_linesize;
805  uint8_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
806  uint8_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
807  uint8_t *dst = dst_line;
808 
809  for (y = 0; y < src_h; y++) {
810  const int sum = FFABS(c0_data[x] - 128) + FFABS(c1_data[x] - 128);
811  uint8_t *target;
812  int p;
813 
814  for (p = 256 - sum; p < 256 + sum; p++) {
815  target = dst + x + dst_signed_linesize * p;
816  update(target, max, 1);
817  }
818 
819  c0_data += c0_linesize;
820  c1_data += c1_linesize;
821  dst_data += dst_linesize;
822  }
823  }
824  } else {
825  const uint8_t *c0_data = in->data[(plane + 1) % s->ncomp];
826  const uint8_t *c1_data = in->data[(plane + 2) % s->ncomp];
827  uint8_t *dst_data = out->data[plane] + offset;
828 
829  if (mirror)
830  dst_data += s->size - 1;
831  for (y = 0; y < src_h; y++) {
832  for (x = 0; x < src_w; x++) {
833  const int sum = FFABS(c0_data[x] - 128) + FFABS(c1_data[x] - 128);
834  uint8_t *target;
835  int p;
836 
837  for (p = 256 - sum; p < 256 + sum; p++) {
838  if (mirror)
839  target = dst_data - p;
840  else
841  target = dst_data + p;
842 
843  update(target, max, 1);
844  }
845  }
846 
847  c0_data += c0_linesize;
848  c1_data += c1_linesize;
849  dst_data += dst_linesize;
850  }
851  }
852 
853  envelope(s, out, plane, (plane + 0) % s->ncomp);
854 }
855 
857  int component, int intensity, int offset, int column)
858 {
859  const int plane = s->desc->comp[component].plane;
860  const int mirror = s->mirror;
861  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
862  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
863  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
864  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp];
865  const int max = 255 - intensity;
866  const int src_h = in->height;
867  const int src_w = in->width;
868  int x, y;
869 
870  if (column) {
871  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
872  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
873 
874  for (x = 0; x < src_w; x++) {
875  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
876  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
877  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset * d1_linesize;
878  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset * d2_linesize;
879  uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
880  uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
881  uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
882  uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data);
883 
884  for (y = 0; y < src_h; y++) {
885  const int c1 = c1_data[x] - 128;
886  const int c2 = c2_data[x] - 128;
887  uint8_t *target;
888  int p;
889 
890  for (p = 128 + c1; p < 128; p++) {
891  target = d1 + x + d1_signed_linesize * p;
892  update(target, max, 1);
893  }
894 
895  for (p = 128 + c1 - 1; p > 128; p--) {
896  target = d1 + x + d1_signed_linesize * p;
897  update(target, max, 1);
898  }
899 
900  for (p = 128 + c2; p < 128; p++) {
901  target = d2 + x + d2_signed_linesize * p;
902  update(target, max, 1);
903  }
904 
905  for (p = 128 + c2 - 1; p > 128; p--) {
906  target = d2 + x + d2_signed_linesize * p;
907  update(target, max, 1);
908  }
909 
910  c1_data += c1_linesize;
911  c2_data += c2_linesize;
912  d1_data += d1_linesize;
913  d2_data += d2_linesize;
914  }
915  }
916  } else {
917  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
918  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
919  uint8_t *d0_data = out->data[plane] + offset;
920  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset;
921  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset;
922 
923  if (mirror) {
924  d0_data += s->size - 1;
925  d1_data += s->size - 1;
926  d2_data += s->size - 1;
927  }
928 
929  for (y = 0; y < src_h; y++) {
930  for (x = 0; x < src_w; x++) {
931  const int c1 = c1_data[x] - 128;
932  const int c2 = c2_data[x] - 128;
933  uint8_t *target;
934  int p;
935 
936  for (p = 128 + c1; p < 128; p++) {
937  if (mirror)
938  target = d1_data - p;
939  else
940  target = d1_data + p;
941 
942  update(target, max, 1);
943  }
944 
945  for (p = 128 + 1; p < 128 + c1; p++) {
946  if (mirror)
947  target = d1_data - p;
948  else
949  target = d1_data + p;
950 
951  update(target, max, 1);
952  }
953 
954  for (p = 128 + c2; p < 128; p++) {
955  if (mirror)
956  target = d2_data - p;
957  else
958  target = d2_data + p;
959 
960  update(target, max, 1);
961  }
962 
963  for (p = 128 + 1; p < 128 + c2; p++) {
964  if (mirror)
965  target = d2_data - p;
966  else
967  target = d2_data + p;
968 
969  update(target, max, 1);
970  }
971  }
972 
973  c1_data += c1_linesize;
974  c2_data += c2_linesize;
975  d1_data += d1_linesize;
976  d2_data += d2_linesize;
977  }
978  }
979 
980  envelope(s, out, plane, (plane + 1) % s->ncomp);
981  envelope(s, out, plane, (plane + 2) % s->ncomp);
982 }
983 
985  int component, int intensity, int offset, int column)
986 {
987  const int plane = s->desc->comp[component].plane;
988  const int mirror = s->mirror;
989  const int limit = s->max - 1;
990  const uint16_t *c0_data = (const uint16_t *)in->data[plane + 0];
991  const uint16_t *c1_data = (const uint16_t *)in->data[(plane + 1) % s->ncomp];
992  const uint16_t *c2_data = (const uint16_t *)in->data[(plane + 2) % s->ncomp];
993  const int c0_linesize = in->linesize[ plane + 0 ] / 2;
994  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
995  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
996  const int d0_linesize = out->linesize[ plane + 0 ] / 2;
997  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2;
998  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp] / 2;
999  const int src_h = in->height;
1000  const int src_w = in->width;
1001  int x, y;
1002 
1003  if (s->mode) {
1004  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1005  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1006  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
1007  uint16_t *d0_data = (uint16_t *)out->data[plane] + offset * d0_linesize;
1008  uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset * d1_linesize;
1009  uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset * d2_linesize;
1010  uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1011  uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1012  uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1013  uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1014  uint16_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
1015  uint16_t * const d2 = (mirror ? d2_bottom_line : d2_data);
1016 
1017  for (y = 0; y < src_h; y++) {
1018  for (x = 0; x < src_w; x++) {
1019  const int c0 = FFMIN(c0_data[x], limit);
1020  const int c1 = c1_data[x];
1021  const int c2 = c2_data[x];
1022 
1023  *(d0 + d0_signed_linesize * c0 + x) = c0;
1024  *(d1 + d1_signed_linesize * c0 + x) = c1;
1025  *(d2 + d2_signed_linesize * c0 + x) = c2;
1026  }
1027 
1028  c0_data += c0_linesize;
1029  c1_data += c1_linesize;
1030  c2_data += c2_linesize;
1031  d0_data += d0_linesize;
1032  d1_data += d1_linesize;
1033  d2_data += d2_linesize;
1034  }
1035  } else {
1036  uint16_t *d0_data = (uint16_t *)out->data[plane] + offset;
1037  uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset;
1038  uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset;
1039 
1040  if (mirror) {
1041  d0_data += s->size - 1;
1042  d1_data += s->size - 1;
1043  d2_data += s->size - 1;
1044  }
1045 
1046  for (y = 0; y < src_h; y++) {
1047  for (x = 0; x < src_w; x++) {
1048  const int c0 = FFMIN(c0_data[x], limit);
1049  const int c1 = c1_data[x];
1050  const int c2 = c2_data[x];
1051 
1052  if (mirror) {
1053  *(d0_data - c0) = c0;
1054  *(d1_data - c0) = c1;
1055  *(d2_data - c0) = c2;
1056  } else {
1057  *(d0_data + c0) = c0;
1058  *(d1_data + c0) = c1;
1059  *(d2_data + c0) = c2;
1060  }
1061  }
1062 
1063  c0_data += c0_linesize;
1064  c1_data += c1_linesize;
1065  c2_data += c2_linesize;
1066  d0_data += d0_linesize;
1067  d1_data += d1_linesize;
1068  d2_data += d2_linesize;
1069  }
1070  }
1071 
1072  envelope16(s, out, plane, plane);
1073 }
1074 
1076  int component, int intensity, int offset, int column)
1077 {
1078  const int plane = s->desc->comp[component].plane;
1079  const int mirror = s->mirror;
1080  const uint8_t *c0_data = in->data[plane + 0];
1081  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
1082  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
1083  const int c0_linesize = in->linesize[ plane + 0 ];
1084  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
1085  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
1086  const int d0_linesize = out->linesize[ plane + 0 ];
1087  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
1088  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp];
1089  const int src_h = in->height;
1090  const int src_w = in->width;
1091  int x, y;
1092 
1093  if (s->mode) {
1094  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1095  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1096  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
1097  uint8_t *d0_data = out->data[plane] + offset * d0_linesize;
1098  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset * d1_linesize;
1099  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset * d2_linesize;
1100  uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1101  uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1102  uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1103  uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1104  uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
1105  uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data);
1106 
1107  for (y = 0; y < src_h; y++) {
1108  for (x = 0; x < src_w; x++) {
1109  const int c0 = c0_data[x];
1110  const int c1 = c1_data[x];
1111  const int c2 = c2_data[x];
1112 
1113  *(d0 + d0_signed_linesize * c0 + x) = c0;
1114  *(d1 + d1_signed_linesize * c0 + x) = c1;
1115  *(d2 + d2_signed_linesize * c0 + x) = c2;
1116  }
1117 
1118  c0_data += c0_linesize;
1119  c1_data += c1_linesize;
1120  c2_data += c2_linesize;
1121  d0_data += d0_linesize;
1122  d1_data += d1_linesize;
1123  d2_data += d2_linesize;
1124  }
1125  } else {
1126  uint8_t *d0_data = out->data[plane] + offset;
1127  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset;
1128  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset;
1129 
1130  if (mirror) {
1131  d0_data += s->size - 1;
1132  d1_data += s->size - 1;
1133  d2_data += s->size - 1;
1134  }
1135 
1136  for (y = 0; y < src_h; y++) {
1137  for (x = 0; x < src_w; x++) {
1138  const int c0 = c0_data[x];
1139  const int c1 = c1_data[x];
1140  const int c2 = c2_data[x];
1141 
1142  if (mirror) {
1143  *(d0_data - c0) = c0;
1144  *(d1_data - c0) = c1;
1145  *(d2_data - c0) = c2;
1146  } else {
1147  *(d0_data + c0) = c0;
1148  *(d1_data + c0) = c1;
1149  *(d2_data + c0) = c2;
1150  }
1151  }
1152 
1153  c0_data += c0_linesize;
1154  c1_data += c1_linesize;
1155  c2_data += c2_linesize;
1156  d0_data += d0_linesize;
1157  d1_data += d1_linesize;
1158  d2_data += d2_linesize;
1159  }
1160  }
1161 
1162  envelope(s, out, plane, plane);
1163 }
1164 
1165 static const uint8_t black_yuva_color[4] = { 0, 127, 127, 255 };
1166 static const uint8_t black_gbrp_color[4] = { 0, 0, 0, 255 };
1167 
1168 static int config_input(AVFilterLink *inlink)
1169 {
1170  AVFilterContext *ctx = inlink->dst;
1171  WaveformContext *s = ctx->priv;
1172 
1173  s->desc = av_pix_fmt_desc_get(inlink->format);
1174  s->ncomp = s->desc->nb_components;
1175  s->bits = s->desc->comp[0].depth_minus1 + 1;
1176  s->max = 1 << s->bits;
1177  s->intensity = s->fintensity * (s->max - 1);
1178 
1179  switch (s->filter) {
1180  case LOWPASS:
1181  s->size = 256;
1182  s->waveform = s->bits > 8 ? lowpass16 : lowpass; break;
1183  case FLAT:
1184  s->size = 256 * 3;
1185  s->waveform = flat; break;
1186  case AFLAT:
1187  s->size = 256 * 2;
1188  s->waveform = aflat; break;
1189  case CHROMA:
1190  s->size = 256 * 2;
1191  s->waveform = chroma; break;
1192  case ACHROMA:
1193  s->size = 256;
1194  s->waveform = achroma; break;
1195  case COLOR:
1196  s->size = 256;
1197  s->waveform = s->bits > 8 ? color16 : color; break;
1198  }
1199 
1200  s->size = s->size << (s->bits - 8);
1201 
1202  switch (inlink->format) {
1203  case AV_PIX_FMT_GBRAP:
1204  case AV_PIX_FMT_GBRP:
1205  case AV_PIX_FMT_GBRP9:
1206  case AV_PIX_FMT_GBRP10:
1208  break;
1209  default:
1211  }
1212 
1213  return 0;
1214 }
1215 
1216 static int config_output(AVFilterLink *outlink)
1217 {
1218  AVFilterContext *ctx = outlink->src;
1219  AVFilterLink *inlink = ctx->inputs[0];
1220  WaveformContext *s = ctx->priv;
1221  int comp = 0, i, j = 0, k, p, size, shift;
1222 
1223  for (i = 0; i < s->ncomp; i++) {
1224  if ((1 << i) & s->pcomp)
1225  comp++;
1226  }
1227 
1228  av_freep(&s->peak);
1229 
1230  if (s->mode) {
1231  outlink->h = s->size * FFMAX(comp * s->display, 1);
1232  size = inlink->w;
1233  } else {
1234  outlink->w = s->size * FFMAX(comp * s->display, 1);
1235  size = inlink->h;
1236  }
1237 
1238  s->peak = av_malloc_array(size, 32 * sizeof(*s->peak));
1239  if (!s->peak)
1240  return AVERROR(ENOMEM);
1241 
1242  for (p = 0; p < 4; p++) {
1243  const int is_chroma = (p == 1 || p == 2);
1244  const int shift_w = (is_chroma ? s->desc->log2_chroma_w : 0);
1245  const int shift_h = (is_chroma ? s->desc->log2_chroma_h : 0);
1246  const int plane = s->desc->comp[p].plane;
1247  int offset;
1248 
1249  if (!((1 << p) & s->pcomp))
1250  continue;
1251 
1252  shift = s->mode ? shift_h : shift_w;
1253 
1254  for (k = 0; k < 4; k++) {
1255  s->emax[plane][k] = s->peak + size * (plane * 4 + k + 0);
1256  s->emin[plane][k] = s->peak + size * (plane * 4 + k + 16);
1257  }
1258 
1259  offset = j++ * s->size * s->display;
1260  s->estart[plane] = offset >> shift;
1261  s->eend[plane] = (offset + s->size - 1) >> shift;
1262  for (i = 0; i < size; i++) {
1263  for (k = 0; k < 4; k++) {
1264  s->emax[plane][k][i] = s->estart[plane];
1265  s->emin[plane][k][i] = s->eend[plane];
1266  }
1267  }
1268  }
1269 
1270  outlink->sample_aspect_ratio = (AVRational){1,1};
1271 
1272  return 0;
1273 }
1274 
1275 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
1276 {
1277  AVFilterContext *ctx = inlink->dst;
1278  WaveformContext *s = ctx->priv;
1279  AVFilterLink *outlink = ctx->outputs[0];
1280  AVFrame *out;
1281  int i, j, k;
1282 
1283  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
1284  if (!out) {
1285  av_frame_free(&in);
1286  return AVERROR(ENOMEM);
1287  }
1288  out->pts = in->pts;
1289 
1290  for (k = 0; k < s->ncomp; k++) {
1291  const int is_chroma = (k == 1 || k == 2);
1292  const int dst_h = FF_CEIL_RSHIFT(outlink->h, (is_chroma ? s->desc->log2_chroma_h : 0));
1293  const int dst_w = FF_CEIL_RSHIFT(outlink->w, (is_chroma ? s->desc->log2_chroma_w : 0));
1294  if (s->bits <= 8) {
1295  for (i = 0; i < dst_h ; i++)
1296  memset(out->data[s->desc->comp[k].plane] +
1297  i * out->linesize[s->desc->comp[k].plane],
1298  s->bg_color[k], dst_w);
1299  } else {
1300  const int mult = s->size / 256;
1301  uint16_t *dst = (uint16_t *)out->data[s->desc->comp[k].plane];
1302 
1303  for (i = 0; i < dst_h ; i++) {
1304  for (j = 0; j < dst_w; j++)
1305  dst[j] = s->bg_color[k] * mult;
1306  dst += out->linesize[s->desc->comp[k].plane] / 2;
1307  }
1308  }
1309  }
1310 
1311  for (k = 0, i = 0; k < s->ncomp; k++) {
1312  if ((1 << k) & s->pcomp) {
1313  const int offset = i++ * s->size * s->display;
1314  s->waveform(s, in, out, k, s->intensity, offset, s->mode);
1315  }
1316  }
1317 
1318  av_frame_free(&in);
1319  return ff_filter_frame(outlink, out);
1320 }
1321 
1322 static av_cold void uninit(AVFilterContext *ctx)
1323 {
1324  WaveformContext *s = ctx->priv;
1325 
1326  av_freep(&s->peak);
1327 }
1328 
1329 static const AVFilterPad inputs[] = {
1330  {
1331  .name = "default",
1332  .type = AVMEDIA_TYPE_VIDEO,
1333  .filter_frame = filter_frame,
1334  .config_props = config_input,
1335  },
1336  { NULL }
1337 };
1338 
1339 static const AVFilterPad outputs[] = {
1340  {
1341  .name = "default",
1342  .type = AVMEDIA_TYPE_VIDEO,
1343  .config_props = config_output,
1344  },
1345  { NULL }
1346 };
1347 
1349  .name = "waveform",
1350  .description = NULL_IF_CONFIG_SMALL("Video waveform monitor."),
1351  .priv_size = sizeof(WaveformContext),
1352  .priv_class = &waveform_class,
1354  .uninit = uninit,
1355  .inputs = inputs,
1356  .outputs = outputs,
1357 };
int plane
Definition: avisynth_c.h:291
#define NULL
Definition: coverity.c:32
float v
const char * s
Definition: avisynth_c.h:631
static int shift(int a, int b)
Definition: sonic.c:82
static void lowpass16(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:437
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:409
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2129
This structure describes decoded (raw) audio or video data.
Definition: frame.h:171
AVOption.
Definition: opt.h:255
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:411
static void envelope_peak(WaveformContext *s, AVFrame *out, int plane, int component)
Definition: vf_waveform.c:327
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:412
FilterType
Definition: af_biquads.c:71
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:68
Main libavfilter public API header.
static void envelope_instant16(WaveformContext *s, AVFrame *out, int plane, int component)
Definition: vf_waveform.c:153
static int config_input(AVFilterLink *inlink)
Definition: vf_waveform.c:1168
static enum AVPixelFormat color_pix_fmts[]
Definition: vf_waveform.c:124
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:188
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:396
static void update(uint8_t *target, int max, int intensity)
Definition: vf_waveform.c:429
static int config_output(AVFilterLink *outlink)
Definition: vf_waveform.c:1216
static const AVFilterPad inputs[]
Definition: vf_waveform.c:1329
static void envelope16(WaveformContext *s, AVFrame *out, int plane, int component)
Definition: vf_waveform.c:399
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:109
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
const char * name
Pad name.
Definition: internal.h:69
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:641
#define FLAGS
Definition: vf_waveform.c:67
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1158
static enum AVPixelFormat lowpass_pix_fmts[]
Definition: vf_waveform.c:103
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:103
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:100
uint8_t
#define av_cold
Definition: attributes.h:74
mode
Definition: f_perms.c:27
static void lowpass(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:487
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
static int query_formats(AVFilterContext *ctx)
Definition: vf_waveform.c:132
static const uint8_t black_gbrp_color[4]
Definition: vf_waveform.c:1166
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:257
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:408
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:395
AVFilter ff_vf_waveform
Definition: vf_waveform.c:1348
static void envelope_instant(WaveformContext *s, AVFrame *out, int plane, int component)
Definition: vf_waveform.c:204
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:102
static void color(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:1075
static void update16(uint16_t *target, int max, int intensity, int limit)
Definition: vf_waveform.c:421
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:76
ptrdiff_t size
Definition: opengl_enc.c:101
A filter pad used for either input or output.
Definition: internal.h:63
static void flat(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:534
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:281
uint16_t depth_minus1
Number of bits in the component minus 1.
Definition: pixdesc.h:57
int width
width and height of the video frame
Definition: frame.h:220
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:542
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
AVFILTER_DEFINE_CLASS(waveform)
static void color16(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:984
#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:148
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
void * priv
private data for use by the filter
Definition: avfilter.h:654
simple assert() macros that are a bit more flexible than ISO C assert().
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:383
static const uint8_t offset[127][2]
Definition: vf_spp.c:92
#define FFMAX(a, b)
Definition: common.h:79
static void aflat(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:632
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:67
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:378
#define OFFSET(x)
Definition: vf_waveform.c:66
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
#define FFMIN(a, b)
Definition: common.h:81
float y
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:75
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
#define FF_CEIL_RSHIFT(a, b)
Definition: common.h:57
static enum AVPixelFormat flat_pix_fmts[]
Definition: vf_waveform.c:120
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:68
static void envelope_peak16(WaveformContext *s, AVFrame *out, int plane, int component)
Definition: vf_waveform.c:254
const uint8_t * bg_color
Definition: vf_waveform.c:46
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:413
static void achroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:856
static void envelope(WaveformContext *s, AVFrame *out, int plane, int component)
Definition: vf_waveform.c:410
int * emax[4][4]
Definition: vf_waveform.c:54
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:379
static const AVOption waveform_options[]
Definition: vf_waveform.c:69
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:199
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:280
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
static const AVFilterPad outputs[]
Definition: vf_waveform.c:1339
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
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_waveform.c:1322
static int16_t mult(Float11 *f1, Float11 *f2)
Definition: g726.c:55
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:380
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:69
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:470
rational number numerator/denominator
Definition: rational.h:43
static void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:785
const char * name
Filter name.
Definition: avfilter.h:474
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:377
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:648
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:209
int * emin[4][4]
Definition: vf_waveform.c:55
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:381
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:182
uint16_t plane
Which of the 4 planes contains the component.
Definition: pixdesc.h:34
static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
void(* waveform)(struct WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset, int column)
Definition: vf_waveform.c:61
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:63
Y , 8bpp.
Definition: pixfmt.h:71
if(ret< 0)
Definition: vf_mcdeint.c:280
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:299
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:410
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:77
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:70
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_waveform.c:1275
static const uint8_t black_yuva_color[4]
Definition: vf_waveform.c:1165
A list of supported formats for one end of a filter link.
Definition: formats.h:64
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:302
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-> out
An instance of a filter.
Definition: avfilter.h:633
int height
Definition: frame.h:220
#define av_freep(p)
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
Definition: eamad.c:83
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:101
void INT64 start
Definition: avisynth_c.h:553
#define av_malloc_array(a, b)
internal API functions
const AVPixFmtDescriptor * desc
Definition: vf_waveform.c:63
AVPixelFormat
Pixel format.
Definition: pixfmt.h:61
for(j=16;j >0;--j)