FFmpeg
vf_datascope.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/parseutils.h"
25 #include "libavutil/pixdesc.h"
27 #include "avfilter.h"
28 #include "drawutils.h"
29 #include "formats.h"
30 #include "internal.h"
31 #include "video.h"
32 
33 typedef struct DatascopeContext {
34  const AVClass *class;
35  int ow, oh;
36  int x, y;
37  int mode;
38  int dformat;
39  int axis;
41  float opacity;
42 
43  int nb_planes;
44  int nb_comps;
45  int chars;
51 
52  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
54  int (*filter)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
56 
57 #define OFFSET(x) offsetof(DatascopeContext, x)
58 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
59 #define FLAGSR AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
60 
61 static const AVOption datascope_options[] = {
62  { "size", "set output size", OFFSET(ow), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, FLAGS },
63  { "s", "set output size", OFFSET(ow), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, FLAGS },
64  { "x", "set x offset", OFFSET(x), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGSR },
65  { "y", "set y offset", OFFSET(y), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGSR },
66  { "mode", "set scope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGSR, "mode" },
67  { "mono", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGSR, "mode" },
68  { "color", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGSR, "mode" },
69  { "color2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGSR, "mode" },
70  { "axis", "draw column/row numbers", OFFSET(axis), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGSR },
71  { "opacity", "set background opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGSR },
72  { "format", "set display number format", OFFSET(dformat), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGSR, "format" },
73  { "hex", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGSR, "format" },
74  { "dec", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGSR, "format" },
75  { "components", "set components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=15}, 1, 15, FLAGSR },
76  { NULL }
77 };
78 
79 AVFILTER_DEFINE_CLASS(datascope);
80 
82 {
84 }
85 
87  int x0, int y0, const uint8_t *text, int vertical)
88 {
89  int x = x0;
90 
91  for (; *text; text++) {
92  if (*text == '\n') {
93  x = x0;
94  y0 += 8;
95  continue;
96  }
97  ff_blend_mask(draw, color, frame->data, frame->linesize,
98  frame->width, frame->height,
99  avpriv_cga_font + *text * 8, 1, 8, 8, 0, 0, x, y0);
100  if (vertical) {
101  x = x0;
102  y0 += 8;
103  } else {
104  x += 8;
105  }
106  }
107 }
108 
109 static void pick_color8(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
110 {
111  int p, i;
112 
113  color->rgba[3] = 255;
114  for (p = 0; p < draw->nb_planes; p++) {
115  if (draw->nb_planes == 1) {
116  for (i = 0; i < 4; i++) {
117  value[i] = in->data[0][y * in->linesize[0] + x * draw->pixelstep[0] + i];
118  color->comp[0].u8[i] = value[i];
119  }
120  } else {
121  value[p] = in->data[p][(y >> draw->vsub[p]) * in->linesize[p] + (x >> draw->hsub[p])];
122  color->comp[p].u8[0] = value[p];
123  }
124  }
125 }
126 
127 static void pick_color16(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
128 {
129  int p, i;
130 
131  color->rgba[3] = 255;
132  for (p = 0; p < draw->nb_planes; p++) {
133  if (draw->nb_planes == 1) {
134  for (i = 0; i < 4; i++) {
135  value[i] = AV_RL16(in->data[0] + y * in->linesize[0] + x * draw->pixelstep[0] + i * 2);
136  color->comp[0].u16[i] = value[i];
137  }
138  } else {
139  value[p] = AV_RL16(in->data[p] + (y >> draw->vsub[p]) * in->linesize[p] + (x >> draw->hsub[p]) * 2);
140  color->comp[p].u16[0] = value[p];
141  }
142  }
143 }
144 
146 {
147  int p;
148 
149  reverse->rgba[3] = 255;
150  for (p = 0; p < draw->nb_planes; p++) {
151  reverse->comp[p].u8[0] = color->comp[p].u8[0] > 127 ? 0 : 255;
152  reverse->comp[p].u8[1] = color->comp[p].u8[1] > 127 ? 0 : 255;
153  reverse->comp[p].u8[2] = color->comp[p].u8[2] > 127 ? 0 : 255;
154  }
155 }
156 
158 {
159  int p;
160 
161  reverse->rgba[3] = 255;
162  for (p = 0; p < draw->nb_planes; p++) {
163  const unsigned max = (1 << draw->desc->comp[p].depth) - 1;
164  const unsigned mid = (max + 1) / 2;
165 
166  reverse->comp[p].u16[0] = color->comp[p].u16[0] > mid ? 0 : max;
167  reverse->comp[p].u16[1] = color->comp[p].u16[1] > mid ? 0 : max;
168  reverse->comp[p].u16[2] = color->comp[p].u16[2] > mid ? 0 : max;
169  }
170 }
171 
172 typedef struct ThreadData {
173  AVFrame *in, *out;
174  int xoff, yoff, PP;
175 } ThreadData;
176 
177 static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
178 {
179  DatascopeContext *s = ctx->priv;
180  AVFilterLink *outlink = ctx->outputs[0];
181  AVFilterLink *inlink = ctx->inputs[0];
182  ThreadData *td = arg;
183  AVFrame *in = td->in;
184  AVFrame *out = td->out;
185  const int PP = td->PP;
186  const int xoff = td->xoff;
187  const int yoff = td->yoff;
188  const int P = FFMAX(s->nb_planes, s->nb_comps);
189  const int C = s->chars;
190  const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2;
191  const int W = (outlink->w - xoff) / (C * 10);
192  const int H = (outlink->h - yoff) / (PP * 12);
193  const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"};
194  const int slice_start = (W * jobnr) / nb_jobs;
195  const int slice_end = (W * (jobnr+1)) / nb_jobs;
196  int x, y, p;
197 
198  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
199  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
200  FFDrawColor color = { { 0 } };
201  FFDrawColor reverse = { { 0 } };
202  int value[4] = { 0 }, pp = 0;
203 
204  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
205  s->reverse_color(&s->draw, &color, &reverse);
206  ff_fill_rectangle(&s->draw, &color, out->data, out->linesize,
207  xoff + x * C * 10, yoff + y * PP * 12, C * 10, PP * 12);
208 
209  for (p = 0; p < P; p++) {
210  char text[256];
211 
212  if (!(s->components & (1 << p)))
213  continue;
214  snprintf(text, sizeof(text), format[D], value[p]);
215  draw_text(&s->draw, out, &reverse, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0);
216  pp++;
217  }
218  }
219  }
220 
221  return 0;
222 }
223 
224 static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
225 {
226  DatascopeContext *s = ctx->priv;
227  AVFilterLink *outlink = ctx->outputs[0];
228  AVFilterLink *inlink = ctx->inputs[0];
229  ThreadData *td = arg;
230  AVFrame *in = td->in;
231  AVFrame *out = td->out;
232  const int PP = td->PP;
233  const int xoff = td->xoff;
234  const int yoff = td->yoff;
235  const int P = FFMAX(s->nb_planes, s->nb_comps);
236  const int C = s->chars;
237  const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2;
238  const int W = (outlink->w - xoff) / (C * 10);
239  const int H = (outlink->h - yoff) / (PP * 12);
240  const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"};
241  const int slice_start = (W * jobnr) / nb_jobs;
242  const int slice_end = (W * (jobnr+1)) / nb_jobs;
243  int x, y, p;
244 
245  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
246  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
247  FFDrawColor color = { { 0 } };
248  int value[4] = { 0 }, pp = 0;
249 
250  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
251 
252  for (p = 0; p < P; p++) {
253  char text[256];
254 
255  if (!(s->components & (1 << p)))
256  continue;
257  snprintf(text, sizeof(text), format[D], value[p]);
258  draw_text(&s->draw, out, &color, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0);
259  pp++;
260  }
261  }
262  }
263 
264  return 0;
265 }
266 
267 static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
268 {
269  DatascopeContext *s = ctx->priv;
270  AVFilterLink *outlink = ctx->outputs[0];
271  AVFilterLink *inlink = ctx->inputs[0];
272  ThreadData *td = arg;
273  AVFrame *in = td->in;
274  AVFrame *out = td->out;
275  const int PP = td->PP;
276  const int xoff = td->xoff;
277  const int yoff = td->yoff;
278  const int P = FFMAX(s->nb_planes, s->nb_comps);
279  const int C = s->chars;
280  const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2;
281  const int W = (outlink->w - xoff) / (C * 10);
282  const int H = (outlink->h - yoff) / (PP * 12);
283  const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"};
284  const int slice_start = (W * jobnr) / nb_jobs;
285  const int slice_end = (W * (jobnr+1)) / nb_jobs;
286  int x, y, p;
287 
288  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
289  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
290  FFDrawColor color = { { 0 } };
291  int value[4] = { 0 }, pp = 0;
292 
293  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
294  for (p = 0; p < P; p++) {
295  char text[256];
296 
297  if (!(s->components & (1 << p)))
298  continue;
299  snprintf(text, sizeof(text), format[D], value[p]);
300  draw_text(&s->draw, out, &s->white, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0);
301  pp++;
302  }
303  }
304  }
305 
306  return 0;
307 }
308 
310 {
311  AVFilterContext *ctx = inlink->dst;
312  DatascopeContext *s = ctx->priv;
313  AVFilterLink *outlink = ctx->outputs[0];
314  const int P = FFMAX(s->nb_planes, s->nb_comps);
315  ThreadData td = { 0 };
316  int ymaxlen = 0;
317  int xmaxlen = 0;
318  int PP = 0;
319  AVFrame *out;
320 
321  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
322  if (!out) {
323  av_frame_free(&in);
324  return AVERROR(ENOMEM);
325  }
326  out->pts = in->pts;
327 
328  ff_fill_rectangle(&s->draw, &s->black, out->data, out->linesize,
329  0, 0, outlink->w, outlink->h);
330 
331  for (int p = 0; p < P; p++) {
332  if (s->components & (1 << p))
333  PP++;
334  }
335  PP = FFMAX(PP, 1);
336 
337  if (s->axis) {
338  const int C = s->chars;
339  int Y = outlink->h / (PP * 12);
340  int X = outlink->w / (C * 10);
341  char text[256] = { 0 };
342  int x, y;
343 
344  snprintf(text, sizeof(text), "%d", s->y + Y);
345  ymaxlen = strlen(text);
346  ymaxlen *= 10;
347  snprintf(text, sizeof(text), "%d", s->x + X);
348  xmaxlen = strlen(text);
349  xmaxlen *= 10;
350 
351  Y = (outlink->h - xmaxlen) / (PP * 12);
352  X = (outlink->w - ymaxlen) / (C * 10);
353 
354  for (y = 0; y < Y; y++) {
355  snprintf(text, sizeof(text), "%d", s->y + y);
356 
357  ff_fill_rectangle(&s->draw, &s->gray, out->data, out->linesize,
358  0, xmaxlen + y * PP * 12 + (PP + 1) * PP - 2, ymaxlen, 10);
359 
360  draw_text(&s->draw, out, &s->yellow, 2, xmaxlen + y * PP * 12 + (PP + 1) * PP, text, 0);
361  }
362 
363  for (x = 0; x < X; x++) {
364  snprintf(text, sizeof(text), "%d", s->x + x);
365 
366  ff_fill_rectangle(&s->draw, &s->gray, out->data, out->linesize,
367  ymaxlen + x * C * 10 + 2 * C - 2, 0, 10, xmaxlen);
368 
369  draw_text(&s->draw, out, &s->yellow, ymaxlen + x * C * 10 + 2 * C, 2, text, 1);
370  }
371  }
372 
373  td.in = in; td.out = out, td.yoff = xmaxlen, td.xoff = ymaxlen, td.PP = PP;
374  ctx->internal->execute(ctx, s->filter, &td, NULL, FFMIN(ff_filter_get_nb_threads(ctx), FFMAX(outlink->w / 20, 1)));
375 
376  av_frame_free(&in);
377  return ff_filter_frame(outlink, out);
378 }
379 
381 {
382  DatascopeContext *s = inlink->dst->priv;
383  uint8_t alpha = s->opacity * 255;
384 
385  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
386  ff_draw_init(&s->draw, inlink->format, 0);
387  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
388  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, alpha} );
389  ff_draw_color(&s->draw, &s->yellow, (uint8_t[]){ 255, 255, 0, 255} );
390  ff_draw_color(&s->draw, &s->gray, (uint8_t[]){ 77, 77, 77, 255} );
391  s->chars = (s->draw.desc->comp[0].depth + 7) / 8 * 2 + s->dformat;
392  s->nb_comps = s->draw.desc->nb_components;
393 
394  switch (s->mode) {
395  case 0: s->filter = filter_mono; break;
396  case 1: s->filter = filter_color; break;
397  case 2: s->filter = filter_color2; break;
398  }
399 
400  if (s->draw.desc->comp[0].depth <= 8) {
401  s->pick_color = pick_color8;
402  s->reverse_color = reverse_color8;
403  } else {
404  s->pick_color = pick_color16;
405  s->reverse_color = reverse_color16;
406  }
407 
408  return 0;
409 }
410 
411 static int config_output(AVFilterLink *outlink)
412 {
413  DatascopeContext *s = outlink->src->priv;
414 
415  outlink->h = s->oh;
416  outlink->w = s->ow;
417  outlink->sample_aspect_ratio = (AVRational){1,1};
418 
419  return 0;
420 }
421 
422 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
423  char *res, int res_len, int flags)
424 {
425  int ret;
426 
427  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
428  if (ret < 0)
429  return ret;
430 
431  return config_input(ctx->inputs[0]);
432 }
433 
434 static const AVFilterPad inputs[] = {
435  {
436  .name = "default",
437  .type = AVMEDIA_TYPE_VIDEO,
438  .filter_frame = filter_frame,
439  .config_props = config_input,
440  },
441  { NULL }
442 };
443 
444 static const AVFilterPad outputs[] = {
445  {
446  .name = "default",
447  .type = AVMEDIA_TYPE_VIDEO,
448  .config_props = config_output,
449  },
450  { NULL }
451 };
452 
454  .name = "datascope",
455  .description = NULL_IF_CONFIG_SMALL("Video data analysis."),
456  .priv_size = sizeof(DatascopeContext),
457  .priv_class = &datascope_class,
459  .inputs = inputs,
460  .outputs = outputs,
463 };
464 
465 typedef struct PixscopeContext {
466  const AVClass *class;
467 
468  float xpos, ypos;
469  float wx, wy;
470  int w, h;
471  float o;
472 
473  int x, y;
474  int ww, wh;
475 
477  int nb_comps;
478  int is_rgb;
479  uint8_t rgba_map[4];
488 
489  uint16_t values[4][80][80];
490 
491  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
493 
494 #define POFFSET(x) offsetof(PixscopeContext, x)
495 
496 static const AVOption pixscope_options[] = {
497  { "x", "set scope x offset", POFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
498  { "y", "set scope y offset", POFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
499  { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGSR },
500  { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGSR },
501  { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
502  { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGSR },
503  { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGSR },
504  { NULL }
505 };
506 
507 AVFILTER_DEFINE_CLASS(pixscope);
508 
510 {
511  PixscopeContext *s = inlink->dst->priv;
512 
513  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
514  ff_draw_init(&s->draw, inlink->format, 0);
515  ff_draw_color(&s->draw, &s->dark, (uint8_t[]){ 0, 0, 0, s->o * 255} );
516  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, 255} );
517  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
518  ff_draw_color(&s->draw, &s->green, (uint8_t[]){ 0, 255, 0, 255} );
519  ff_draw_color(&s->draw, &s->blue, (uint8_t[]){ 0, 0, 255, 255} );
520  ff_draw_color(&s->draw, &s->red, (uint8_t[]){ 255, 0, 0, 255} );
521  s->nb_comps = s->draw.desc->nb_components;
522  s->is_rgb = s->draw.desc->flags & AV_PIX_FMT_FLAG_RGB;
523 
524  if (s->is_rgb) {
525  s->colors[0] = &s->red;
526  s->colors[1] = &s->green;
527  s->colors[2] = &s->blue;
528  s->colors[3] = &s->white;
529  ff_fill_rgba_map(s->rgba_map, inlink->format);
530  } else {
531  s->colors[0] = &s->white;
532  s->colors[1] = &s->blue;
533  s->colors[2] = &s->red;
534  s->colors[3] = &s->white;
535  s->rgba_map[0] = 0;
536  s->rgba_map[1] = 1;
537  s->rgba_map[2] = 2;
538  s->rgba_map[3] = 3;
539  }
540 
541  if (s->draw.desc->comp[0].depth <= 8) {
542  s->pick_color = pick_color8;
543  } else {
544  s->pick_color = pick_color16;
545  }
546 
547  if (inlink->w < 640 || inlink->h < 480) {
548  av_log(inlink->dst, AV_LOG_ERROR, "min supported resolution is 640x480\n");
549  return AVERROR(EINVAL);
550  }
551 
552  s->ww = 300;
553  s->wh = 300 * 1.6;
554  s->x = s->xpos * (inlink->w - 1);
555  s->y = s->ypos * (inlink->h - 1);
556  if (s->x + s->w >= inlink->w || s->y + s->h >= inlink->h) {
557  av_log(inlink->dst, AV_LOG_WARNING, "scope position is out of range, clipping\n");
558  s->x = FFMIN(s->x, inlink->w - s->w);
559  s->y = FFMIN(s->y, inlink->h - s->h);
560  }
561 
562  return 0;
563 }
564 
565 #define SQR(x) ((x)*(x))
566 
568 {
569  AVFilterContext *ctx = inlink->dst;
570  PixscopeContext *s = ctx->priv;
571  AVFilterLink *outlink = ctx->outputs[0];
572  AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height);
573  int max[4] = { 0 }, min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
574  float average[4] = { 0 };
575  double std[4] = { 0 }, rms[4] = { 0 };
576  const char rgba[4] = { 'R', 'G', 'B', 'A' };
577  const char yuva[4] = { 'Y', 'U', 'V', 'A' };
578  int x, y, X, Y, i, w, h;
579  char text[128];
580 
581  if (!out) {
582  av_frame_free(&in);
583  return AVERROR(ENOMEM);
584  }
586  av_frame_copy(out, in);
587 
588  w = s->ww / s->w;
589  h = s->ww / s->h;
590 
591  if (s->wx >= 0) {
592  X = (in->width - s->ww) * s->wx;
593  } else {
594  X = (in->width - s->ww) * -s->wx;
595  }
596  if (s->wy >= 0) {
597  Y = (in->height - s->wh) * s->wy;
598  } else {
599  Y = (in->height - s->wh) * -s->wy;
600  }
601 
602  if (s->wx < 0) {
603  if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) &&
604  s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) {
605  X = (in->width - s->ww) * (1 + s->wx);
606  }
607  }
608 
609  if (s->wy < 0) {
610  if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) &&
611  s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) {
612  Y = (in->height - s->wh) * (1 + s->wy);
613  }
614  }
615 
616  ff_blend_rectangle(&s->draw, &s->dark, out->data, out->linesize,
617  out->width, out->height,
618  X,
619  Y,
620  s->ww,
621  s->wh);
622 
623  for (y = 0; y < s->h; y++) {
624  for (x = 0; x < s->w; x++) {
625  FFDrawColor color = { { 0 } };
626  int value[4] = { 0 };
627 
628  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
629  ff_fill_rectangle(&s->draw, &color, out->data, out->linesize,
630  x * w + (s->ww - 4 - (s->w * w)) / 2 + X, y * h + 2 + Y, w, h);
631  for (i = 0; i < 4; i++) {
632  s->values[i][x][y] = value[i];
633  rms[i] += (double)value[i] * (double)value[i];
634  average[i] += value[i];
635  min[i] = FFMIN(min[i], value[i]);
636  max[i] = FFMAX(max[i], value[i]);
637  }
638  }
639  }
640 
641  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
642  out->width, out->height,
643  s->x - 2, s->y - 2, s->w + 4, 1);
644 
645  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
646  out->width, out->height,
647  s->x - 1, s->y - 1, s->w + 2, 1);
648 
649  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
650  out->width, out->height,
651  s->x - 1, s->y - 1, 1, s->h + 2);
652 
653  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
654  out->width, out->height,
655  s->x - 2, s->y - 2, 1, s->h + 4);
656 
657  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
658  out->width, out->height,
659  s->x - 1, s->y + 1 + s->h, s->w + 3, 1);
660 
661  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
662  out->width, out->height,
663  s->x - 2, s->y + 2 + s->h, s->w + 4, 1);
664 
665  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
666  out->width, out->height,
667  s->x + 1 + s->w, s->y - 1, 1, s->h + 2);
668 
669  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
670  out->width, out->height,
671  s->x + 2 + s->w, s->y - 2, 1, s->h + 5);
672 
673  for (i = 0; i < 4; i++) {
674  rms[i] /= s->w * s->h;
675  rms[i] = sqrt(rms[i]);
676  average[i] /= s->w * s->h;
677  }
678 
679  for (y = 0; y < s->h; y++) {
680  for (x = 0; x < s->w; x++) {
681  for (i = 0; i < 4; i++)
682  std[i] += SQR(s->values[i][x][y] - average[i]);
683  }
684  }
685 
686  for (i = 0; i < 4; i++) {
687  std[i] /= s->w * s->h;
688  std[i] = sqrt(std[i]);
689  }
690 
691  snprintf(text, sizeof(text), "CH AVG MIN MAX RMS\n");
692  draw_text(&s->draw, out, &s->white, X + 28, Y + s->ww + 5, text, 0);
693  for (i = 0; i < s->nb_comps; i++) {
694  int c = s->rgba_map[i];
695 
696  snprintf(text, sizeof(text), "%c %07.1f %05d %05d %07.1f\n", s->is_rgb ? rgba[i] : yuva[i], average[c], min[c], max[c], rms[c]);
697  draw_text(&s->draw, out, s->colors[i], X + 28, Y + s->ww + 15 * (i + 1), text, 0);
698  }
699  snprintf(text, sizeof(text), "CH STD\n");
700  draw_text(&s->draw, out, &s->white, X + 28, Y + s->ww + 15 * (0 + 5), text, 0);
701  for (i = 0; i < s->nb_comps; i++) {
702  int c = s->rgba_map[i];
703 
704  snprintf(text, sizeof(text), "%c %07.2f\n", s->is_rgb ? rgba[i] : yuva[i], std[c]);
705  draw_text(&s->draw, out, s->colors[i], X + 28, Y + s->ww + 15 * (i + 6), text, 0);
706  }
707 
708  av_frame_free(&in);
709  return ff_filter_frame(outlink, out);
710 }
711 
712 static int pixscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
713  char *res, int res_len, int flags)
714 {
715  int ret;
716 
717  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
718  if (ret < 0)
719  return ret;
720 
721  return pixscope_config_input(ctx->inputs[0]);
722 }
723 
724 static const AVFilterPad pixscope_inputs[] = {
725  {
726  .name = "default",
727  .type = AVMEDIA_TYPE_VIDEO,
728  .filter_frame = pixscope_filter_frame,
729  .config_props = pixscope_config_input,
730  },
731  { NULL }
732 };
733 
734 static const AVFilterPad pixscope_outputs[] = {
735  {
736  .name = "default",
737  .type = AVMEDIA_TYPE_VIDEO,
738  },
739  { NULL }
740 };
741 
743  .name = "pixscope",
744  .description = NULL_IF_CONFIG_SMALL("Pixel data analysis."),
745  .priv_size = sizeof(PixscopeContext),
746  .priv_class = &pixscope_class,
752 };
753 
754 typedef struct PixelValues {
755  uint16_t p[4];
756 } PixelValues;
757 
758 typedef struct OscilloscopeContext {
759  const AVClass *class;
760 
761  float xpos, ypos;
762  float tx, ty;
763  float size;
764  float tilt;
765  float theight, twidth;
766  float o;
768  int grid;
770  int scope;
771 
772  int x1, y1, x2, y2;
773  int ox, oy;
774  int height, width;
775 
776  int max;
778  int nb_comps;
779  int is_rgb;
780  uint8_t rgba_map[4];
792 
795 
796  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
799 
800 #define OOFFSET(x) offsetof(OscilloscopeContext, x)
801 
802 static const AVOption oscilloscope_options[] = {
803  { "x", "set scope x position", OOFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
804  { "y", "set scope y position", OOFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
805  { "s", "set scope size", OOFFSET(size), AV_OPT_TYPE_FLOAT, {.dbl=0.8}, 0, 1, FLAGSR },
806  { "t", "set scope tilt", OOFFSET(tilt), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
807  { "o", "set trace opacity", OOFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.8}, 0, 1, FLAGSR },
808  { "tx", "set trace x position", OOFFSET(tx), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
809  { "ty", "set trace y position", OOFFSET(ty), AV_OPT_TYPE_FLOAT, {.dbl=0.9}, 0, 1, FLAGSR },
810  { "tw", "set trace width", OOFFSET(twidth), AV_OPT_TYPE_FLOAT, {.dbl=0.8},.1, 1, FLAGSR },
811  { "th", "set trace height", OOFFSET(theight), AV_OPT_TYPE_FLOAT, {.dbl=0.3},.1, 1, FLAGSR },
812  { "c", "set components to trace", OOFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, FLAGSR },
813  { "g", "draw trace grid", OOFFSET(grid), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
814  { "st", "draw statistics", OOFFSET(statistics), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
815  { "sc", "draw scope", OOFFSET(scope), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
816  { NULL }
817 };
818 
819 AVFILTER_DEFINE_CLASS(oscilloscope);
820 
822 {
823  OscilloscopeContext *s = ctx->priv;
824 
825  av_freep(&s->values);
826 }
827 
828 static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1,
830 {
831  int dx = FFABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
832  int dy = FFABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
833  int err = (dx > dy ? dx : -dy) / 2, e2;
834  int p, i;
835 
836  for (;;) {
837  if (x0 >= 0 && y0 >= 0 && x0 < out->width && y0 < out->height) {
838  for (p = 0; p < draw->nb_planes; p++) {
839  if (draw->desc->comp[p].depth == 8) {
840  if (draw->nb_planes == 1) {
841  for (i = 0; i < draw->desc->nb_components; i++) {
842  out->data[0][y0 * out->linesize[0] + x0 * draw->pixelstep[0] + i] = color->comp[0].u8[i];
843  }
844  } else {
845  out->data[p][out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p])] = color->comp[p].u8[0];
846  }
847  } else {
848  if (draw->nb_planes == 1) {
849  for (i = 0; i < draw->desc->nb_components; i++) {
850  AV_WN16(out->data[0] + y0 * out->linesize[0] + (x0 * draw->pixelstep[0] + i), color->comp[0].u16[i]);
851  }
852  } else {
853  AV_WN16(out->data[p] + out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p]) * 2, color->comp[p].u16[0]);
854  }
855  }
856  }
857  }
858 
859  if (x0 == x1 && y0 == y1)
860  break;
861 
862  e2 = err;
863 
864  if (e2 >-dx) {
865  err -= dy;
866  x0 += sx;
867  }
868 
869  if (e2 < dy) {
870  err += dx;
871  y0 += sy;
872  }
873  }
874 }
875 
877 {
878  int i, c;
879 
880  for (i = 1; i < s->nb_values; i++) {
881  for (c = 0; c < s->nb_comps; c++) {
882  if ((1 << c) & s->components) {
883  int x = i * s->width / s->nb_values;
884  int px = (i - 1) * s->width / s->nb_values;
885  int py = s->height - s->values[i-1].p[s->rgba_map[c]] * s->height / 256;
886  int y = s->height - s->values[i].p[s->rgba_map[c]] * s->height / 256;
887 
888  draw_line(&s->draw, s->ox + x, s->oy + y, s->ox + px, s->oy + py, frame, s->colors[c]);
889  }
890  }
891  }
892 }
893 
894 
896 {
897  int i, c;
898 
899  for (i = 1; i < s->nb_values; i++) {
900  for (c = 0; c < s->nb_comps; c++) {
901  if ((1 << c) & s->components) {
902  int x = i * s->width / s->nb_values;
903  int px = (i - 1) * s->width / s->nb_values;
904  int py = s->height - s->values[i-1].p[s->rgba_map[c]] * s->height / s->max;
905  int y = s->height - s->values[i].p[s->rgba_map[c]] * s->height / s->max;
906 
907  draw_line(&s->draw, s->ox + x, s->oy + y, s->ox + px, s->oy + py, frame, s->colors[c]);
908  }
909  }
910  }
911 }
912 
914 {
915  OscilloscopeContext *s = ctx->priv;
916  AVFilterLink *inlink = ctx->inputs[0];
917  int cx, cy, size;
918  double tilt;
919 
920  ff_draw_color(&s->draw, &s->dark, (uint8_t[]){ 0, 0, 0, s->o * 255} );
921  s->height = s->theight * inlink->h;
922  s->width = s->twidth * inlink->w;
923  size = hypot(inlink->w, inlink->h);
924  size *= s->size;
925  tilt = (s->tilt - 0.5) * M_PI;
926  cx = s->xpos * (inlink->w - 1);
927  cy = s->ypos * (inlink->h - 1);
928  s->x1 = cx - size / 2.0 * cos(tilt);
929  s->x2 = cx + size / 2.0 * cos(tilt);
930  s->y1 = cy - size / 2.0 * sin(tilt);
931  s->y2 = cy + size / 2.0 * sin(tilt);
932  s->ox = (inlink->w - s->width) * s->tx;
933  s->oy = (inlink->h - s->height) * s->ty;
934 }
935 
937 {
938  OscilloscopeContext *s = inlink->dst->priv;
939  int size;
940 
941  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
942  ff_draw_init(&s->draw, inlink->format, 0);
943  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, 255} );
944  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
945  ff_draw_color(&s->draw, &s->green, (uint8_t[]){ 0, 255, 0, 255} );
946  ff_draw_color(&s->draw, &s->blue, (uint8_t[]){ 0, 0, 255, 255} );
947  ff_draw_color(&s->draw, &s->red, (uint8_t[]){ 255, 0, 0, 255} );
948  ff_draw_color(&s->draw, &s->cyan, (uint8_t[]){ 0, 255, 255, 255} );
949  ff_draw_color(&s->draw, &s->magenta, (uint8_t[]){ 255, 0, 255, 255} );
950  ff_draw_color(&s->draw, &s->gray, (uint8_t[]){ 128, 128, 128, 255} );
951  s->nb_comps = s->draw.desc->nb_components;
952  s->is_rgb = s->draw.desc->flags & AV_PIX_FMT_FLAG_RGB;
953 
954  if (s->is_rgb) {
955  s->colors[0] = &s->red;
956  s->colors[1] = &s->green;
957  s->colors[2] = &s->blue;
958  s->colors[3] = &s->white;
959  ff_fill_rgba_map(s->rgba_map, inlink->format);
960  } else {
961  s->colors[0] = &s->white;
962  s->colors[1] = &s->cyan;
963  s->colors[2] = &s->magenta;
964  s->colors[3] = &s->white;
965  s->rgba_map[0] = 0;
966  s->rgba_map[1] = 1;
967  s->rgba_map[2] = 2;
968  s->rgba_map[3] = 3;
969  }
970 
971  if (s->draw.desc->comp[0].depth <= 8) {
972  s->pick_color = pick_color8;
973  s->draw_trace = draw_trace8;
974  } else {
975  s->pick_color = pick_color16;
976  s->draw_trace = draw_trace16;
977  }
978 
979  s->max = (1 << s->draw.desc->comp[0].depth);
980  size = hypot(inlink->w, inlink->h);
981 
982  s->values = av_calloc(size, sizeof(*s->values));
983  if (!s->values)
984  return AVERROR(ENOMEM);
985 
987 
988  return 0;
989 }
990 
991 static void draw_scope(OscilloscopeContext *s, int x0, int y0, int x1, int y1,
992  AVFrame *out, PixelValues *p, int state)
993 {
994  int dx = FFABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
995  int dy = FFABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
996  int err = (dx > dy ? dx : -dy) / 2, e2;
997 
998  for (;;) {
999  if (x0 >= 0 && y0 >= 0 && x0 < out->width && y0 < out->height) {
1000  FFDrawColor color = { { 0 } };
1001  int value[4] = { 0 };
1002 
1003  s->pick_color(&s->draw, &color, out, x0, y0, value);
1004  s->values[s->nb_values].p[0] = value[0];
1005  s->values[s->nb_values].p[1] = value[1];
1006  s->values[s->nb_values].p[2] = value[2];
1007  s->values[s->nb_values].p[3] = value[3];
1008  s->nb_values++;
1009 
1010  if (s->scope) {
1011  if (s->draw.desc->comp[0].depth == 8) {
1012  if (s->draw.nb_planes == 1) {
1013  int i;
1014 
1015  for (i = 0; i < s->nb_comps; i++)
1016  out->data[0][out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i] = 255 * ((s->nb_values + state) & 1);
1017  } else {
1018  out->data[0][out->linesize[0] * y0 + x0] = 255 * ((s->nb_values + state) & 1);
1019  }
1020  } else {
1021  if (s->draw.nb_planes == 1) {
1022  int i;
1023 
1024  for (i = 0; i < s->nb_comps; i++)
1025  AV_WN16(out->data[0] + out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i, (s->max - 1) * ((s->nb_values + state) & 1));
1026  } else {
1027  AV_WN16(out->data[0] + out->linesize[0] * y0 + 2 * x0, (s->max - 1) * ((s->nb_values + state) & 1));
1028  }
1029  }
1030  }
1031  }
1032 
1033  if (x0 == x1 && y0 == y1)
1034  break;
1035 
1036  e2 = err;
1037 
1038  if (e2 >-dx) {
1039  err -= dy;
1040  x0 += sx;
1041  }
1042 
1043  if (e2 < dy) {
1044  err += dx;
1045  y0 += sy;
1046  }
1047  }
1048 }
1049 
1051 {
1052  AVFilterContext *ctx = inlink->dst;
1053  OscilloscopeContext *s = ctx->priv;
1054  AVFilterLink *outlink = ctx->outputs[0];
1055  float average[4] = { 0 };
1056  int max[4] = { 0 };
1057  int min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
1058  int i, c;
1059 
1060  s->nb_values = 0;
1061  draw_scope(s, s->x1, s->y1, s->x2, s->y2, frame, s->values, inlink->frame_count_in & 1);
1062  ff_blend_rectangle(&s->draw, &s->dark, frame->data, frame->linesize,
1063  frame->width, frame->height,
1064  s->ox, s->oy, s->width, s->height + 20 * s->statistics);
1065 
1066  if (s->grid && outlink->h >= 10) {
1067  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1068  s->ox, s->oy, s->width - 1, 1);
1069 
1070  for (i = 1; i < 5; i++) {
1071  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1072  s->ox, s->oy + i * (s->height - 1) / 4, s->width, 1);
1073  }
1074 
1075  for (i = 0; i < 10; i++) {
1076  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1077  s->ox + i * (s->width - 1) / 10, s->oy, 1, s->height);
1078  }
1079 
1080  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1081  s->ox + s->width - 1, s->oy, 1, s->height);
1082  }
1083 
1084  s->draw_trace(s, frame);
1085 
1086  for (i = 0; i < s->nb_values; i++) {
1087  for (c = 0; c < s->nb_comps; c++) {
1088  if ((1 << c) & s->components) {
1089  max[c] = FFMAX(max[c], s->values[i].p[s->rgba_map[c]]);
1090  min[c] = FFMIN(min[c], s->values[i].p[s->rgba_map[c]]);
1091  average[c] += s->values[i].p[s->rgba_map[c]];
1092  }
1093  }
1094  }
1095  for (c = 0; c < s->nb_comps; c++) {
1096  average[c] /= s->nb_values;
1097  }
1098 
1099  if (s->statistics && s->height > 10 && s->width > 280 * av_popcount(s->components)) {
1100  for (c = 0, i = 0; c < s->nb_comps; c++) {
1101  if ((1 << c) & s->components) {
1102  const char rgba[4] = { 'R', 'G', 'B', 'A' };
1103  const char yuva[4] = { 'Y', 'U', 'V', 'A' };
1104  char text[128];
1105 
1106  snprintf(text, sizeof(text), "%c avg:%.1f min:%d max:%d\n", s->is_rgb ? rgba[c] : yuva[c], average[c], min[c], max[c]);
1107  draw_text(&s->draw, frame, &s->white, s->ox + 2 + 280 * i++, s->oy + s->height + 4, text, 0);
1108  }
1109  }
1110  }
1111 
1112  return ff_filter_frame(outlink, frame);
1113 }
1114 
1115 static int oscilloscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
1116  char *res, int res_len, int flags)
1117 {
1118  int ret;
1119 
1120  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
1121  if (ret < 0)
1122  return ret;
1123 
1125 
1126  return 0;
1127 }
1128 
1130  {
1131  .name = "default",
1132  .type = AVMEDIA_TYPE_VIDEO,
1133  .filter_frame = oscilloscope_filter_frame,
1134  .config_props = oscilloscope_config_input,
1135  .needs_writable = 1,
1136  },
1137  { NULL }
1138 };
1139 
1141  {
1142  .name = "default",
1143  .type = AVMEDIA_TYPE_VIDEO,
1144  },
1145  { NULL }
1146 };
1147 
1149  .name = "oscilloscope",
1150  .description = NULL_IF_CONFIG_SMALL("2D Video Oscilloscope."),
1151  .priv_size = sizeof(OscilloscopeContext),
1152  .priv_class = &oscilloscope_class,
1159 };
OscilloscopeContext::o
float o
Definition: vf_datascope.c:766
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:187
PixscopeContext::colors
FFDrawColor * colors[4]
Definition: vf_datascope.c:487
td
#define td
Definition: regdef.h:70
FFDrawColor
Definition: drawutils.h:49
DatascopeContext::components
int components
Definition: vf_datascope.c:40
DatascopeContext::x
int x
Definition: vf_datascope.c:36
W
@ W
Definition: vf_addroi.c:26
reverse_color8
static void reverse_color8(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:145
pixscope_inputs
static const AVFilterPad pixscope_inputs[]
Definition: vf_datascope.c:724
OscilloscopeContext::oy
int oy
Definition: vf_datascope.c:773
filter_mono
static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:267
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
OscilloscopeContext::components
int components
Definition: vf_datascope.c:767
PixscopeContext::x
int x
Definition: vf_datascope.c:473
out
FILE * out
Definition: movenc.c:54
pixscope_outputs
static const AVFilterPad pixscope_outputs[]
Definition: vf_datascope.c:734
DatascopeContext::dformat
int dformat
Definition: vf_datascope.c:38
PixscopeContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_datascope.c:479
color
Definition: vf_paletteuse.c:583
pixscope_process_command
static int pixscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_datascope.c:712
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:978
filter_color2
static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:177
OscilloscopeContext::theight
float theight
Definition: vf_datascope.c:765
X
@ X
Definition: vf_addroi.c:26
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
state
static struct @321 state
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:111
DatascopeContext::gray
FFDrawColor gray
Definition: vf_datascope.c:50
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
PixscopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:480
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:396
FFDrawContext::desc
const struct AVPixFmtDescriptor * desc
Definition: drawutils.h:36
AVFrame::width
int width
Definition: frame.h:361
w
uint8_t w
Definition: llviddspenc.c:39
FFDrawColor::u16
uint16_t u16[8]
Definition: drawutils.h:53
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:58
AVOption
AVOption.
Definition: opt.h:248
OscilloscopeContext::ox
int ox
Definition: vf_datascope.c:773
FFDrawColor::rgba
uint8_t rgba[4]
Definition: drawutils.h:50
DatascopeContext::opacity
float opacity
Definition: vf_datascope.c:41
PixscopeContext::dark
FFDrawColor dark
Definition: vf_datascope.c:481
max
#define max(a, b)
Definition: cuda_runtime.h:33
PixscopeContext::y
int y
Definition: vf_datascope.c:473
OFFSET
#define OFFSET(x)
Definition: vf_datascope.c:57
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
FFDrawContext::nb_planes
unsigned nb_planes
Definition: drawutils.h:38
OOFFSET
#define OOFFSET(x)
Definition: vf_datascope.c:800
av_popcount
#define av_popcount
Definition: common.h:176
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:502
pick_color8
static void pick_color8(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:109
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1554
OscilloscopeContext::max
int max
Definition: vf_datascope.c:776
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:317
D
D(D(float, sse)
Definition: rematrix_init.c:29
FFDrawContext::pixelstep
int pixelstep[MAX_PLANES]
Definition: drawutils.h:39
formats.h
OscilloscopeContext::white
FFDrawColor white
Definition: vf_datascope.c:784
OscilloscopeContext::draw_trace
void(* draw_trace)(struct OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:797
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2581
OscilloscopeContext::gray
FFDrawColor gray
Definition: vf_datascope.c:790
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:348
ThreadData::yoff
int yoff
Definition: vf_datascope.c:174
DatascopeContext::chars
int chars
Definition: vf_datascope.c:45
OscilloscopeContext::y1
int y1
Definition: vf_datascope.c:772
FFDrawColor::comp
union FFDrawColor::@204 comp[MAX_PLANES]
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_datascope.c:422
ff_blend_mask
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, const uint8_t *mask, int mask_linesize, int mask_w, int mask_h, int l2depth, unsigned endianness, int x0, int y0)
Blend an alpha mask with an uniform color.
Definition: drawutils.c:528
PixscopeContext::is_rgb
int is_rgb
Definition: vf_datascope.c:478
PixscopeContext::blue
FFDrawColor blue
Definition: vf_datascope.c:485
DatascopeContext::reverse_color
void(* reverse_color)(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:53
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
C
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the C
Definition: writing_filters.txt:58
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:181
update_oscilloscope
static void update_oscilloscope(AVFilterContext *ctx)
Definition: vf_datascope.c:913
PixscopeContext::values
uint16_t values[4][80][80]
Definition: vf_datascope.c:489
OscilloscopeContext::ty
float ty
Definition: vf_datascope.c:762
ff_set_common_formats
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:580
PixscopeContext::w
int w
Definition: vf_datascope.c:470
filter_color
static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:224
OscilloscopeContext::y2
int y2
Definition: vf_datascope.c:772
DatascopeContext::filter
int(* filter)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:54
OscilloscopeContext::ypos
float ypos
Definition: vf_datascope.c:761
width
#define width
intreadwrite.h
oscilloscope_uninit
static void oscilloscope_uninit(AVFilterContext *ctx)
Definition: vf_datascope.c:821
s
#define s(width, name)
Definition: cbs_vp9.c:257
PixelValues::p
uint16_t p[4]
Definition: vf_datascope.c:755
PixscopeContext::wy
float wy
Definition: vf_datascope.c:469
FFDrawContext::vsub
uint8_t vsub[MAX_PLANES]
Definition: drawutils.h:42
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_datascope.c:380
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2031
inputs
static const AVFilterPad inputs[]
Definition: vf_datascope.c:434
OscilloscopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:777
PixscopeContext::red
FFDrawColor red
Definition: vf_datascope.c:486
oscilloscope_outputs
static const AVFilterPad oscilloscope_outputs[]
Definition: vf_datascope.c:1140
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
OscilloscopeContext::height
int height
Definition: vf_datascope.c:774
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
Definition: drawutils.c:84
pick_color16
static void pick_color16(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:127
DatascopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:46
PixscopeContext::green
FFDrawColor green
Definition: vf_datascope.c:484
OscilloscopeContext::nb_values
int nb_values
Definition: vf_datascope.c:793
reverse_color16
static void reverse_color16(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:157
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_datascope.c:81
arg
const char * arg
Definition: jacosubdec.c:67
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
POFFSET
#define POFFSET(x)
Definition: vf_datascope.c:494
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:536
PixscopeContext::white
FFDrawColor white
Definition: vf_datascope.c:483
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:72
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
OscilloscopeContext::magenta
FFDrawColor magenta
Definition: vf_datascope.c:789
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
Definition: opt.h:235
parseutils.h
DatascopeContext
Definition: vf_datascope.c:33
OscilloscopeContext::colors
FFDrawColor * colors[4]
Definition: vf_datascope.c:791
DatascopeContext::oh
int oh
Definition: vf_datascope.c:35
datascope_options
static const AVOption datascope_options[]
Definition: vf_datascope.c:61
oscilloscope_options
static const AVOption oscilloscope_options[]
Definition: vf_datascope.c:802
PixscopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:476
FFDrawColor::u8
uint8_t u8[16]
Definition: drawutils.h:54
DatascopeContext::pick_color
void(* pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:52
OscilloscopeContext::tx
float tx
Definition: vf_datascope.c:762
draw_trace8
static void draw_trace8(OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:876
PixscopeContext::o
float o
Definition: vf_datascope.c:471
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(datascope)
OscilloscopeContext::red
FFDrawColor red
Definition: vf_datascope.c:787
draw_trace16
static void draw_trace16(OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:895
DatascopeContext::ow
int ow
Definition: vf_datascope.c:35
OscilloscopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:778
PixscopeContext::wh
int wh
Definition: vf_datascope.c:474
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_datascope.c:309
DatascopeContext::mode
int mode
Definition: vf_datascope.c:37
FLAGS
#define FLAGS
Definition: vf_datascope.c:58
AV_PIX_FMT_FLAG_RGB
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:137
ThreadData::PP
int PP
Definition: vf_datascope.c:174
P
#define P
ff_blend_rectangle
void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, int x0, int y0, int w, int h)
Blend a rectangle with an uniform color.
Definition: drawutils.c:351
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:677
oscilloscope_process_command
static int oscilloscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_datascope.c:1115
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
outputs
static const AVFilterPad outputs[]
Definition: vf_datascope.c:444
size
int size
Definition: twinvq_data.h:10344
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
draw_text
static void draw_text(FFDrawContext *draw, AVFrame *frame, FFDrawColor *color, int x0, int y0, const uint8_t *text, int vertical)
Definition: vf_datascope.c:86
oscilloscope_inputs
static const AVFilterPad oscilloscope_inputs[]
Definition: vf_datascope.c:1129
ff_fill_rectangle
void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_x, int dst_y, int w, int h)
Fill a rectangle with an uniform color.
Definition: drawutils.c:224
OscilloscopeContext::cyan
FFDrawColor cyan
Definition: vf_datascope.c:788
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:842
pixscope_filter_frame
static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_datascope.c:567
height
#define height
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
H
#define H
Definition: pixlet.c:39
OscilloscopeContext::pick_color
void(* pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:796
OscilloscopeContext::size
float size
Definition: vf_datascope.c:763
xga_font_data.h
OscilloscopeContext::x1
int x1
Definition: vf_datascope.c:772
DatascopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:44
M_PI
#define M_PI
Definition: mathematics.h:52
Y
#define Y
Definition: boxblur.h:38
ff_vf_pixscope
const AVFilter ff_vf_pixscope
Definition: vf_datascope.c:742
internal.h
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:126
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
OscilloscopeContext::scope
int scope
Definition: vf_datascope.c:770
OscilloscopeContext
Definition: vf_datascope.c:758
i
int i
Definition: input.c:407
OscilloscopeContext::black
FFDrawColor black
Definition: vf_datascope.c:783
PixscopeContext
Definition: vf_datascope.c:465
OscilloscopeContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_datascope.c:780
SQR
#define SQR(x)
Definition: vf_datascope.c:565
DatascopeContext::white
FFDrawColor white
Definition: vf_datascope.c:48
OscilloscopeContext::tilt
float tilt
Definition: vf_datascope.c:764
DatascopeContext::y
int y
Definition: vf_datascope.c:36
OscilloscopeContext::statistics
int statistics
Definition: vf_datascope.c:769
ff_draw_supported_pixel_formats
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
Definition: drawutils.c:637
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:762
OscilloscopeContext::green
FFDrawColor green
Definition: vf_datascope.c:785
OscilloscopeContext::xpos
float xpos
Definition: vf_datascope.c:761
ThreadData
Used for passing data between threads.
Definition: dsddec.c:67
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
DatascopeContext::black
FFDrawColor black
Definition: vf_datascope.c:49
DatascopeContext::axis
int axis
Definition: vf_datascope.c:39
FFDrawContext
Definition: drawutils.h:35
OscilloscopeContext::dark
FFDrawColor dark
Definition: vf_datascope.c:782
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
FLAGSR
#define FLAGSR
Definition: vf_datascope.c:59
OscilloscopeContext::is_rgb
int is_rgb
Definition: vf_datascope.c:779
DatascopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:43
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:137
AVFilter
Filter definition.
Definition: avfilter.h:145
PixscopeContext::pick_color
void(* pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:491
ThreadData::xoff
int xoff
Definition: vf_datascope.c:174
ret
ret
Definition: filter_design.txt:187
PixscopeContext::black
FFDrawColor black
Definition: vf_datascope.c:482
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
FFDrawContext::hsub
uint8_t hsub[MAX_PLANES]
Definition: drawutils.h:41
OscilloscopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:781
ff_vf_oscilloscope
const AVFilter ff_vf_oscilloscope
Definition: vf_datascope.c:1148
OscilloscopeContext::twidth
float twidth
Definition: vf_datascope.c:765
AVFrame::height
int height
Definition: frame.h:361
OscilloscopeContext::grid
int grid
Definition: vf_datascope.c:768
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:251
PixscopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:477
mode
mode
Definition: ebur128.h:83
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
PixscopeContext::xpos
float xpos
Definition: vf_datascope.c:468
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:106
PixscopeContext::ypos
float ypos
Definition: vf_datascope.c:468
AVFilterContext
An instance of a filter.
Definition: avfilter.h:333
PixscopeContext::h
int h
Definition: vf_datascope.c:470
OscilloscopeContext::width
int width
Definition: vf_datascope.c:774
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
ff_vf_datascope
const AVFilter ff_vf_datascope
Definition: vf_datascope.c:453
ThreadData::in
AVFrame * in
Definition: af_adenorm.c:223
PixscopeContext::wx
float wx
Definition: vf_datascope.c:469
draw_scope
static void draw_scope(OscilloscopeContext *s, int x0, int y0, int x1, int y1, AVFrame *out, PixelValues *p, int state)
Definition: vf_datascope.c:991
avpriv_cga_font
const uint8_t avpriv_cga_font[2048]
Definition: xga_font_data.c:29
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_datascope.c:411
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:242
draw_line
static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1, AVFrame *out, FFDrawColor *color)
Definition: vf_datascope.c:828
pixscope_options
static const AVOption pixscope_options[]
Definition: vf_datascope.c:496
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
pixscope_config_input
static int pixscope_config_input(AVFilterLink *inlink)
Definition: vf_datascope.c:509
format
fg outputs[0] format
Definition: ffmpeg_filter.c:175
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
DatascopeContext::yellow
FFDrawColor yellow
Definition: vf_datascope.c:47
OscilloscopeContext::blue
FFDrawColor blue
Definition: vf_datascope.c:786
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:334
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
h
h
Definition: vp9dsp_template.c:2038
OscilloscopeContext::values
PixelValues * values
Definition: vf_datascope.c:794
drawutils.h
OscilloscopeContext::x2
int x2
Definition: vf_datascope.c:772
int
int
Definition: ffmpeg_filter.c:156
PixelValues
Definition: vf_datascope.c:754
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
snprintf
#define snprintf
Definition: snprintf.h:34
oscilloscope_filter_frame
static int oscilloscope_filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: vf_datascope.c:1050
PixscopeContext::ww
int ww
Definition: vf_datascope.c:474
oscilloscope_config_input
static int oscilloscope_config_input(AVFilterLink *inlink)
Definition: vf_datascope.c:936
min
float min
Definition: vorbis_enc_data.h:456
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:372