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/intreadwrite.h"
22 #include "libavutil/opt.h"
23 #include "libavutil/parseutils.h"
24 #include "libavutil/pixdesc.h"
26 #include "avfilter.h"
27 #include "drawutils.h"
28 #include "formats.h"
29 #include "internal.h"
30 #include "video.h"
31 
32 typedef struct DatascopeContext {
33  const AVClass *class;
34  int ow, oh;
35  int x, y;
36  int mode;
37  int dformat;
38  int axis;
40  float opacity;
41 
42  int nb_planes;
43  int nb_comps;
44  int chars;
50 
51  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
53  int (*filter)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
55 
56 #define OFFSET(x) offsetof(DatascopeContext, x)
57 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
58 #define FLAGSR AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
59 
60 static const AVOption datascope_options[] = {
61  { "size", "set output size", OFFSET(ow), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, FLAGS },
62  { "s", "set output size", OFFSET(ow), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, FLAGS },
63  { "x", "set x offset", OFFSET(x), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGSR },
64  { "y", "set y offset", OFFSET(y), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGSR },
65  { "mode", "set scope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGSR, "mode" },
66  { "mono", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGSR, "mode" },
67  { "color", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGSR, "mode" },
68  { "color2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGSR, "mode" },
69  { "axis", "draw column/row numbers", OFFSET(axis), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGSR },
70  { "opacity", "set background opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGSR },
71  { "format", "set display number format", OFFSET(dformat), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGSR, "format" },
72  { "hex", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGSR, "format" },
73  { "dec", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGSR, "format" },
74  { "components", "set components to display", OFFSET(components), AV_OPT_TYPE_INT, {.i64=15}, 1, 15, FLAGSR },
75  { NULL }
76 };
77 
78 AVFILTER_DEFINE_CLASS(datascope);
79 
81 {
83 }
84 
86  int x0, int y0, const uint8_t *text, int vertical)
87 {
88  int x = x0;
89 
90  for (; *text; text++) {
91  if (*text == '\n') {
92  x = x0;
93  y0 += 8;
94  continue;
95  }
96  ff_blend_mask(draw, color, frame->data, frame->linesize,
97  frame->width, frame->height,
98  avpriv_cga_font + *text * 8, 1, 8, 8, 0, 0, x, y0);
99  if (vertical) {
100  x = x0;
101  y0 += 8;
102  } else {
103  x += 8;
104  }
105  }
106 }
107 
108 static void pick_color8(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
109 {
110  int p, i;
111 
112  color->rgba[3] = 255;
113  for (p = 0; p < draw->nb_planes; p++) {
114  if (draw->nb_planes == 1) {
115  for (i = 0; i < 4; i++) {
116  value[i] = in->data[0][y * in->linesize[0] + x * draw->pixelstep[0] + i];
117  color->comp[0].u8[i] = value[i];
118  }
119  } else {
120  value[p] = in->data[p][(y >> draw->vsub[p]) * in->linesize[p] + (x >> draw->hsub[p])];
121  color->comp[p].u8[0] = value[p];
122  }
123  }
124 }
125 
126 static void pick_color16(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
127 {
128  int p, i;
129 
130  color->rgba[3] = 255;
131  for (p = 0; p < draw->nb_planes; p++) {
132  if (draw->nb_planes == 1) {
133  for (i = 0; i < 4; i++) {
134  value[i] = AV_RL16(in->data[0] + y * in->linesize[0] + x * draw->pixelstep[0] + i * 2);
135  color->comp[0].u16[i] = value[i];
136  }
137  } else {
138  value[p] = AV_RL16(in->data[p] + (y >> draw->vsub[p]) * in->linesize[p] + (x >> draw->hsub[p]) * 2);
139  color->comp[p].u16[0] = value[p];
140  }
141  }
142 }
143 
145 {
146  int p;
147 
148  reverse->rgba[3] = 255;
149  for (p = 0; p < draw->nb_planes; p++) {
150  reverse->comp[p].u8[0] = color->comp[p].u8[0] > 127 ? 0 : 255;
151  reverse->comp[p].u8[1] = color->comp[p].u8[1] > 127 ? 0 : 255;
152  reverse->comp[p].u8[2] = color->comp[p].u8[2] > 127 ? 0 : 255;
153  }
154 }
155 
157 {
158  int p;
159 
160  reverse->rgba[3] = 255;
161  for (p = 0; p < draw->nb_planes; p++) {
162  const unsigned max = (1 << draw->desc->comp[p].depth) - 1;
163  const unsigned mid = (max + 1) / 2;
164 
165  reverse->comp[p].u16[0] = color->comp[p].u16[0] > mid ? 0 : max;
166  reverse->comp[p].u16[1] = color->comp[p].u16[1] > mid ? 0 : max;
167  reverse->comp[p].u16[2] = color->comp[p].u16[2] > mid ? 0 : max;
168  }
169 }
170 
171 typedef struct ThreadData {
172  AVFrame *in, *out;
173  int xoff, yoff, PP;
174 } ThreadData;
175 
176 static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
177 {
178  DatascopeContext *s = ctx->priv;
179  AVFilterLink *outlink = ctx->outputs[0];
180  AVFilterLink *inlink = ctx->inputs[0];
181  ThreadData *td = arg;
182  AVFrame *in = td->in;
183  AVFrame *out = td->out;
184  const int PP = td->PP;
185  const int xoff = td->xoff;
186  const int yoff = td->yoff;
187  const int P = FFMAX(s->nb_planes, s->nb_comps);
188  const int C = s->chars;
189  const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2;
190  const int W = (outlink->w - xoff) / (C * 10);
191  const int H = (outlink->h - yoff) / (PP * 12);
192  const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"};
193  const int slice_start = (W * jobnr) / nb_jobs;
194  const int slice_end = (W * (jobnr+1)) / nb_jobs;
195  int x, y, p;
196 
197  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
198  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
199  FFDrawColor color = { { 0 } };
200  FFDrawColor reverse = { { 0 } };
201  int value[4] = { 0 }, pp = 0;
202 
203  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
204  s->reverse_color(&s->draw, &color, &reverse);
205  ff_fill_rectangle(&s->draw, &color, out->data, out->linesize,
206  xoff + x * C * 10, yoff + y * PP * 12, C * 10, PP * 12);
207 
208  for (p = 0; p < P; p++) {
209  char text[256];
210 
211  if (!(s->components & (1 << p)))
212  continue;
213  snprintf(text, sizeof(text), format[D], value[p]);
214  draw_text(&s->draw, out, &reverse, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0);
215  pp++;
216  }
217  }
218  }
219 
220  return 0;
221 }
222 
223 static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
224 {
225  DatascopeContext *s = ctx->priv;
226  AVFilterLink *outlink = ctx->outputs[0];
227  AVFilterLink *inlink = ctx->inputs[0];
228  ThreadData *td = arg;
229  AVFrame *in = td->in;
230  AVFrame *out = td->out;
231  const int PP = td->PP;
232  const int xoff = td->xoff;
233  const int yoff = td->yoff;
234  const int P = FFMAX(s->nb_planes, s->nb_comps);
235  const int C = s->chars;
236  const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2;
237  const int W = (outlink->w - xoff) / (C * 10);
238  const int H = (outlink->h - yoff) / (PP * 12);
239  const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"};
240  const int slice_start = (W * jobnr) / nb_jobs;
241  const int slice_end = (W * (jobnr+1)) / nb_jobs;
242  int x, y, p;
243 
244  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
245  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
246  FFDrawColor color = { { 0 } };
247  int value[4] = { 0 }, pp = 0;
248 
249  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
250 
251  for (p = 0; p < P; p++) {
252  char text[256];
253 
254  if (!(s->components & (1 << p)))
255  continue;
256  snprintf(text, sizeof(text), format[D], value[p]);
257  draw_text(&s->draw, out, &color, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0);
258  pp++;
259  }
260  }
261  }
262 
263  return 0;
264 }
265 
266 static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
267 {
268  DatascopeContext *s = ctx->priv;
269  AVFilterLink *outlink = ctx->outputs[0];
270  AVFilterLink *inlink = ctx->inputs[0];
271  ThreadData *td = arg;
272  AVFrame *in = td->in;
273  AVFrame *out = td->out;
274  const int PP = td->PP;
275  const int xoff = td->xoff;
276  const int yoff = td->yoff;
277  const int P = FFMAX(s->nb_planes, s->nb_comps);
278  const int C = s->chars;
279  const int D = ((s->chars - s->dformat) >> 2) + s->dformat * 2;
280  const int W = (outlink->w - xoff) / (C * 10);
281  const int H = (outlink->h - yoff) / (PP * 12);
282  const char *format[4] = {"%02X\n", "%04X\n", "%03d\n", "%05d\n"};
283  const int slice_start = (W * jobnr) / nb_jobs;
284  const int slice_end = (W * (jobnr+1)) / nb_jobs;
285  int x, y, p;
286 
287  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
288  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
289  FFDrawColor color = { { 0 } };
290  int value[4] = { 0 }, pp = 0;
291 
292  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
293  for (p = 0; p < P; p++) {
294  char text[256];
295 
296  if (!(s->components & (1 << p)))
297  continue;
298  snprintf(text, sizeof(text), format[D], value[p]);
299  draw_text(&s->draw, out, &s->white, xoff + x * C * 10 + 2, yoff + y * PP * 12 + pp * 10 + 2, text, 0);
300  pp++;
301  }
302  }
303  }
304 
305  return 0;
306 }
307 
309 {
310  AVFilterContext *ctx = inlink->dst;
311  DatascopeContext *s = ctx->priv;
312  AVFilterLink *outlink = ctx->outputs[0];
313  const int P = FFMAX(s->nb_planes, s->nb_comps);
314  ThreadData td = { 0 };
315  int ymaxlen = 0;
316  int xmaxlen = 0;
317  int PP = 0;
318  AVFrame *out;
319 
320  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
321  if (!out) {
322  av_frame_free(&in);
323  return AVERROR(ENOMEM);
324  }
325  out->pts = in->pts;
326 
327  ff_fill_rectangle(&s->draw, &s->black, out->data, out->linesize,
328  0, 0, outlink->w, outlink->h);
329 
330  for (int p = 0; p < P; p++) {
331  if (s->components & (1 << p))
332  PP++;
333  }
334  PP = FFMAX(PP, 1);
335 
336  if (s->axis) {
337  const int C = s->chars;
338  int Y = outlink->h / (PP * 12);
339  int X = outlink->w / (C * 10);
340  char text[256] = { 0 };
341  int x, y;
342 
343  snprintf(text, sizeof(text), "%d", s->y + Y);
344  ymaxlen = strlen(text);
345  ymaxlen *= 10;
346  snprintf(text, sizeof(text), "%d", s->x + X);
347  xmaxlen = strlen(text);
348  xmaxlen *= 10;
349 
350  Y = (outlink->h - xmaxlen) / (PP * 12);
351  X = (outlink->w - ymaxlen) / (C * 10);
352 
353  for (y = 0; y < Y; y++) {
354  snprintf(text, sizeof(text), "%d", s->y + y);
355 
356  ff_fill_rectangle(&s->draw, &s->gray, out->data, out->linesize,
357  0, xmaxlen + y * PP * 12 + (PP + 1) * PP - 2, ymaxlen, 10);
358 
359  draw_text(&s->draw, out, &s->yellow, 2, xmaxlen + y * PP * 12 + (PP + 1) * PP, text, 0);
360  }
361 
362  for (x = 0; x < X; x++) {
363  snprintf(text, sizeof(text), "%d", s->x + x);
364 
365  ff_fill_rectangle(&s->draw, &s->gray, out->data, out->linesize,
366  ymaxlen + x * C * 10 + 2 * C - 2, 0, 10, xmaxlen);
367 
368  draw_text(&s->draw, out, &s->yellow, ymaxlen + x * C * 10 + 2 * C, 2, text, 1);
369  }
370  }
371 
372  td.in = in; td.out = out, td.yoff = xmaxlen, td.xoff = ymaxlen, td.PP = PP;
373  ctx->internal->execute(ctx, s->filter, &td, NULL, FFMIN(ff_filter_get_nb_threads(ctx), FFMAX(outlink->w / 20, 1)));
374 
375  av_frame_free(&in);
376  return ff_filter_frame(outlink, out);
377 }
378 
380 {
381  DatascopeContext *s = inlink->dst->priv;
382  uint8_t alpha = s->opacity * 255;
383 
384  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
385  ff_draw_init(&s->draw, inlink->format, 0);
386  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
387  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, alpha} );
388  ff_draw_color(&s->draw, &s->yellow, (uint8_t[]){ 255, 255, 0, 255} );
389  ff_draw_color(&s->draw, &s->gray, (uint8_t[]){ 77, 77, 77, 255} );
390  s->chars = (s->draw.desc->comp[0].depth + 7) / 8 * 2 + s->dformat;
391  s->nb_comps = s->draw.desc->nb_components;
392 
393  switch (s->mode) {
394  case 0: s->filter = filter_mono; break;
395  case 1: s->filter = filter_color; break;
396  case 2: s->filter = filter_color2; break;
397  }
398 
399  if (s->draw.desc->comp[0].depth <= 8) {
400  s->pick_color = pick_color8;
401  s->reverse_color = reverse_color8;
402  } else {
403  s->pick_color = pick_color16;
404  s->reverse_color = reverse_color16;
405  }
406 
407  return 0;
408 }
409 
410 static int config_output(AVFilterLink *outlink)
411 {
412  DatascopeContext *s = outlink->src->priv;
413 
414  outlink->h = s->oh;
415  outlink->w = s->ow;
416  outlink->sample_aspect_ratio = (AVRational){1,1};
417 
418  return 0;
419 }
420 
421 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
422  char *res, int res_len, int flags)
423 {
424  int ret;
425 
426  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
427  if (ret < 0)
428  return ret;
429 
430  return config_input(ctx->inputs[0]);
431 }
432 
433 static const AVFilterPad inputs[] = {
434  {
435  .name = "default",
436  .type = AVMEDIA_TYPE_VIDEO,
437  .filter_frame = filter_frame,
438  .config_props = config_input,
439  },
440  { NULL }
441 };
442 
443 static const AVFilterPad outputs[] = {
444  {
445  .name = "default",
446  .type = AVMEDIA_TYPE_VIDEO,
447  .config_props = config_output,
448  },
449  { NULL }
450 };
451 
453  .name = "datascope",
454  .description = NULL_IF_CONFIG_SMALL("Video data analysis."),
455  .priv_size = sizeof(DatascopeContext),
456  .priv_class = &datascope_class,
458  .inputs = inputs,
459  .outputs = outputs,
462 };
463 
464 typedef struct PixscopeContext {
465  const AVClass *class;
466 
467  float xpos, ypos;
468  float wx, wy;
469  int w, h;
470  float o;
471 
472  int x, y;
473  int ww, wh;
474 
476  int nb_comps;
477  int is_rgb;
478  uint8_t rgba_map[4];
487 
488  uint16_t values[4][80][80];
489 
490  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
492 
493 #define POFFSET(x) offsetof(PixscopeContext, x)
494 
495 static const AVOption pixscope_options[] = {
496  { "x", "set scope x offset", POFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
497  { "y", "set scope y offset", POFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
498  { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGSR },
499  { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGSR },
500  { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
501  { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGSR },
502  { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGSR },
503  { NULL }
504 };
505 
506 AVFILTER_DEFINE_CLASS(pixscope);
507 
509 {
510  PixscopeContext *s = inlink->dst->priv;
511 
512  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
513  ff_draw_init(&s->draw, inlink->format, 0);
514  ff_draw_color(&s->draw, &s->dark, (uint8_t[]){ 0, 0, 0, s->o * 255} );
515  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, 255} );
516  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
517  ff_draw_color(&s->draw, &s->green, (uint8_t[]){ 0, 255, 0, 255} );
518  ff_draw_color(&s->draw, &s->blue, (uint8_t[]){ 0, 0, 255, 255} );
519  ff_draw_color(&s->draw, &s->red, (uint8_t[]){ 255, 0, 0, 255} );
520  s->nb_comps = s->draw.desc->nb_components;
521  s->is_rgb = s->draw.desc->flags & AV_PIX_FMT_FLAG_RGB;
522 
523  if (s->is_rgb) {
524  s->colors[0] = &s->red;
525  s->colors[1] = &s->green;
526  s->colors[2] = &s->blue;
527  s->colors[3] = &s->white;
528  ff_fill_rgba_map(s->rgba_map, inlink->format);
529  } else {
530  s->colors[0] = &s->white;
531  s->colors[1] = &s->blue;
532  s->colors[2] = &s->red;
533  s->colors[3] = &s->white;
534  s->rgba_map[0] = 0;
535  s->rgba_map[1] = 1;
536  s->rgba_map[2] = 2;
537  s->rgba_map[3] = 3;
538  }
539 
540  if (s->draw.desc->comp[0].depth <= 8) {
541  s->pick_color = pick_color8;
542  } else {
543  s->pick_color = pick_color16;
544  }
545 
546  if (inlink->w < 640 || inlink->h < 480) {
547  av_log(inlink->dst, AV_LOG_ERROR, "min supported resolution is 640x480\n");
548  return AVERROR(EINVAL);
549  }
550 
551  s->ww = 300;
552  s->wh = 300 * 1.6;
553  s->x = s->xpos * (inlink->w - 1);
554  s->y = s->ypos * (inlink->h - 1);
555  if (s->x + s->w >= inlink->w || s->y + s->h >= inlink->h) {
556  av_log(inlink->dst, AV_LOG_WARNING, "scope position is out of range, clipping\n");
557  s->x = FFMIN(s->x, inlink->w - s->w);
558  s->y = FFMIN(s->y, inlink->h - s->h);
559  }
560 
561  return 0;
562 }
563 
564 #define SQR(x) ((x)*(x))
565 
567 {
568  AVFilterContext *ctx = inlink->dst;
569  PixscopeContext *s = ctx->priv;
570  AVFilterLink *outlink = ctx->outputs[0];
571  AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height);
572  int max[4] = { 0 }, min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
573  float average[4] = { 0 };
574  double std[4] = { 0 }, rms[4] = { 0 };
575  const char rgba[4] = { 'R', 'G', 'B', 'A' };
576  const char yuva[4] = { 'Y', 'U', 'V', 'A' };
577  int x, y, X, Y, i, w, h;
578  char text[128];
579 
580  if (!out) {
581  av_frame_free(&in);
582  return AVERROR(ENOMEM);
583  }
585  av_frame_copy(out, in);
586 
587  w = s->ww / s->w;
588  h = s->ww / s->h;
589 
590  if (s->wx >= 0) {
591  X = (in->width - s->ww) * s->wx;
592  } else {
593  X = (in->width - s->ww) * -s->wx;
594  }
595  if (s->wy >= 0) {
596  Y = (in->height - s->wh) * s->wy;
597  } else {
598  Y = (in->height - s->wh) * -s->wy;
599  }
600 
601  if (s->wx < 0) {
602  if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) &&
603  s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) {
604  X = (in->width - s->ww) * (1 + s->wx);
605  }
606  }
607 
608  if (s->wy < 0) {
609  if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) &&
610  s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) {
611  Y = (in->height - s->wh) * (1 + s->wy);
612  }
613  }
614 
615  ff_blend_rectangle(&s->draw, &s->dark, out->data, out->linesize,
616  out->width, out->height,
617  X,
618  Y,
619  s->ww,
620  s->wh);
621 
622  for (y = 0; y < s->h; y++) {
623  for (x = 0; x < s->w; x++) {
624  FFDrawColor color = { { 0 } };
625  int value[4] = { 0 };
626 
627  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
628  ff_fill_rectangle(&s->draw, &color, out->data, out->linesize,
629  x * w + (s->ww - 4 - (s->w * w)) / 2 + X, y * h + 2 + Y, w, h);
630  for (i = 0; i < 4; i++) {
631  s->values[i][x][y] = value[i];
632  rms[i] += (double)value[i] * (double)value[i];
633  average[i] += value[i];
634  min[i] = FFMIN(min[i], value[i]);
635  max[i] = FFMAX(max[i], value[i]);
636  }
637  }
638  }
639 
640  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
641  out->width, out->height,
642  s->x - 2, s->y - 2, s->w + 4, 1);
643 
644  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
645  out->width, out->height,
646  s->x - 1, s->y - 1, s->w + 2, 1);
647 
648  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
649  out->width, out->height,
650  s->x - 1, s->y - 1, 1, s->h + 2);
651 
652  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
653  out->width, out->height,
654  s->x - 2, s->y - 2, 1, s->h + 4);
655 
656  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
657  out->width, out->height,
658  s->x - 1, s->y + 1 + s->h, s->w + 3, 1);
659 
660  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
661  out->width, out->height,
662  s->x - 2, s->y + 2 + s->h, s->w + 4, 1);
663 
664  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
665  out->width, out->height,
666  s->x + 1 + s->w, s->y - 1, 1, s->h + 2);
667 
668  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
669  out->width, out->height,
670  s->x + 2 + s->w, s->y - 2, 1, s->h + 5);
671 
672  for (i = 0; i < 4; i++) {
673  rms[i] /= s->w * s->h;
674  rms[i] = sqrt(rms[i]);
675  average[i] /= s->w * s->h;
676  }
677 
678  for (y = 0; y < s->h; y++) {
679  for (x = 0; x < s->w; x++) {
680  for (i = 0; i < 4; i++)
681  std[i] += SQR(s->values[i][x][y] - average[i]);
682  }
683  }
684 
685  for (i = 0; i < 4; i++) {
686  std[i] /= s->w * s->h;
687  std[i] = sqrt(std[i]);
688  }
689 
690  snprintf(text, sizeof(text), "CH AVG MIN MAX RMS\n");
691  draw_text(&s->draw, out, &s->white, X + 28, Y + s->ww + 5, text, 0);
692  for (i = 0; i < s->nb_comps; i++) {
693  int c = s->rgba_map[i];
694 
695  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]);
696  draw_text(&s->draw, out, s->colors[i], X + 28, Y + s->ww + 15 * (i + 1), text, 0);
697  }
698  snprintf(text, sizeof(text), "CH STD\n");
699  draw_text(&s->draw, out, &s->white, X + 28, Y + s->ww + 15 * (0 + 5), text, 0);
700  for (i = 0; i < s->nb_comps; i++) {
701  int c = s->rgba_map[i];
702 
703  snprintf(text, sizeof(text), "%c %07.2f\n", s->is_rgb ? rgba[i] : yuva[i], std[c]);
704  draw_text(&s->draw, out, s->colors[i], X + 28, Y + s->ww + 15 * (i + 6), text, 0);
705  }
706 
707  av_frame_free(&in);
708  return ff_filter_frame(outlink, out);
709 }
710 
711 static int pixscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
712  char *res, int res_len, int flags)
713 {
714  int ret;
715 
716  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
717  if (ret < 0)
718  return ret;
719 
720  return pixscope_config_input(ctx->inputs[0]);
721 }
722 
723 static const AVFilterPad pixscope_inputs[] = {
724  {
725  .name = "default",
726  .type = AVMEDIA_TYPE_VIDEO,
727  .filter_frame = pixscope_filter_frame,
728  .config_props = pixscope_config_input,
729  },
730  { NULL }
731 };
732 
733 static const AVFilterPad pixscope_outputs[] = {
734  {
735  .name = "default",
736  .type = AVMEDIA_TYPE_VIDEO,
737  },
738  { NULL }
739 };
740 
742  .name = "pixscope",
743  .description = NULL_IF_CONFIG_SMALL("Pixel data analysis."),
744  .priv_size = sizeof(PixscopeContext),
745  .priv_class = &pixscope_class,
751 };
752 
753 typedef struct PixelValues {
754  uint16_t p[4];
755 } PixelValues;
756 
757 typedef struct OscilloscopeContext {
758  const AVClass *class;
759 
760  float xpos, ypos;
761  float tx, ty;
762  float size;
763  float tilt;
764  float theight, twidth;
765  float o;
767  int grid;
769  int scope;
770 
771  int x1, y1, x2, y2;
772  int ox, oy;
773  int height, width;
774 
775  int max;
777  int nb_comps;
778  int is_rgb;
779  uint8_t rgba_map[4];
791 
794 
795  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
798 
799 #define OOFFSET(x) offsetof(OscilloscopeContext, x)
800 
801 static const AVOption oscilloscope_options[] = {
802  { "x", "set scope x position", OOFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
803  { "y", "set scope y position", OOFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
804  { "s", "set scope size", OOFFSET(size), AV_OPT_TYPE_FLOAT, {.dbl=0.8}, 0, 1, FLAGSR },
805  { "t", "set scope tilt", OOFFSET(tilt), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
806  { "o", "set trace opacity", OOFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.8}, 0, 1, FLAGSR },
807  { "tx", "set trace x position", OOFFSET(tx), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
808  { "ty", "set trace y position", OOFFSET(ty), AV_OPT_TYPE_FLOAT, {.dbl=0.9}, 0, 1, FLAGSR },
809  { "tw", "set trace width", OOFFSET(twidth), AV_OPT_TYPE_FLOAT, {.dbl=0.8},.1, 1, FLAGSR },
810  { "th", "set trace height", OOFFSET(theight), AV_OPT_TYPE_FLOAT, {.dbl=0.3},.1, 1, FLAGSR },
811  { "c", "set components to trace", OOFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, FLAGSR },
812  { "g", "draw trace grid", OOFFSET(grid), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
813  { "st", "draw statistics", OOFFSET(statistics), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
814  { "sc", "draw scope", OOFFSET(scope), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
815  { NULL }
816 };
817 
818 AVFILTER_DEFINE_CLASS(oscilloscope);
819 
821 {
822  OscilloscopeContext *s = ctx->priv;
823 
824  av_freep(&s->values);
825 }
826 
827 static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1,
829 {
830  int dx = FFABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
831  int dy = FFABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
832  int err = (dx > dy ? dx : -dy) / 2, e2;
833  int p, i;
834 
835  for (;;) {
836  if (x0 >= 0 && y0 >= 0 && x0 < out->width && y0 < out->height) {
837  for (p = 0; p < draw->nb_planes; p++) {
838  if (draw->desc->comp[p].depth == 8) {
839  if (draw->nb_planes == 1) {
840  for (i = 0; i < draw->desc->nb_components; i++) {
841  out->data[0][y0 * out->linesize[0] + x0 * draw->pixelstep[0] + i] = color->comp[0].u8[i];
842  }
843  } else {
844  out->data[p][out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p])] = color->comp[p].u8[0];
845  }
846  } else {
847  if (draw->nb_planes == 1) {
848  for (i = 0; i < draw->desc->nb_components; i++) {
849  AV_WN16(out->data[0] + y0 * out->linesize[0] + (x0 * draw->pixelstep[0] + i), color->comp[0].u16[i]);
850  }
851  } else {
852  AV_WN16(out->data[p] + out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p]) * 2, color->comp[p].u16[0]);
853  }
854  }
855  }
856  }
857 
858  if (x0 == x1 && y0 == y1)
859  break;
860 
861  e2 = err;
862 
863  if (e2 >-dx) {
864  err -= dy;
865  x0 += sx;
866  }
867 
868  if (e2 < dy) {
869  err += dx;
870  y0 += sy;
871  }
872  }
873 }
874 
876 {
877  int i, c;
878 
879  for (i = 1; i < s->nb_values; i++) {
880  for (c = 0; c < s->nb_comps; c++) {
881  if ((1 << c) & s->components) {
882  int x = i * s->width / s->nb_values;
883  int px = (i - 1) * s->width / s->nb_values;
884  int py = s->height - s->values[i-1].p[s->rgba_map[c]] * s->height / 256;
885  int y = s->height - s->values[i].p[s->rgba_map[c]] * s->height / 256;
886 
887  draw_line(&s->draw, s->ox + x, s->oy + y, s->ox + px, s->oy + py, frame, s->colors[c]);
888  }
889  }
890  }
891 }
892 
893 
895 {
896  int i, c;
897 
898  for (i = 1; i < s->nb_values; i++) {
899  for (c = 0; c < s->nb_comps; c++) {
900  if ((1 << c) & s->components) {
901  int x = i * s->width / s->nb_values;
902  int px = (i - 1) * s->width / s->nb_values;
903  int py = s->height - s->values[i-1].p[s->rgba_map[c]] * s->height / s->max;
904  int y = s->height - s->values[i].p[s->rgba_map[c]] * s->height / s->max;
905 
906  draw_line(&s->draw, s->ox + x, s->oy + y, s->ox + px, s->oy + py, frame, s->colors[c]);
907  }
908  }
909  }
910 }
911 
913 {
914  OscilloscopeContext *s = ctx->priv;
915  AVFilterLink *inlink = ctx->inputs[0];
916  int cx, cy, size;
917  double tilt;
918 
919  ff_draw_color(&s->draw, &s->dark, (uint8_t[]){ 0, 0, 0, s->o * 255} );
920  s->height = s->theight * inlink->h;
921  s->width = s->twidth * inlink->w;
922  size = hypot(inlink->w, inlink->h);
923  size *= s->size;
924  tilt = (s->tilt - 0.5) * M_PI;
925  cx = s->xpos * (inlink->w - 1);
926  cy = s->ypos * (inlink->h - 1);
927  s->x1 = cx - size / 2.0 * cos(tilt);
928  s->x2 = cx + size / 2.0 * cos(tilt);
929  s->y1 = cy - size / 2.0 * sin(tilt);
930  s->y2 = cy + size / 2.0 * sin(tilt);
931  s->ox = (inlink->w - s->width) * s->tx;
932  s->oy = (inlink->h - s->height) * s->ty;
933 }
934 
936 {
937  OscilloscopeContext *s = inlink->dst->priv;
938  int size;
939 
940  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
941  ff_draw_init(&s->draw, inlink->format, 0);
942  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, 255} );
943  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
944  ff_draw_color(&s->draw, &s->green, (uint8_t[]){ 0, 255, 0, 255} );
945  ff_draw_color(&s->draw, &s->blue, (uint8_t[]){ 0, 0, 255, 255} );
946  ff_draw_color(&s->draw, &s->red, (uint8_t[]){ 255, 0, 0, 255} );
947  ff_draw_color(&s->draw, &s->cyan, (uint8_t[]){ 0, 255, 255, 255} );
948  ff_draw_color(&s->draw, &s->magenta, (uint8_t[]){ 255, 0, 255, 255} );
949  ff_draw_color(&s->draw, &s->gray, (uint8_t[]){ 128, 128, 128, 255} );
950  s->nb_comps = s->draw.desc->nb_components;
951  s->is_rgb = s->draw.desc->flags & AV_PIX_FMT_FLAG_RGB;
952 
953  if (s->is_rgb) {
954  s->colors[0] = &s->red;
955  s->colors[1] = &s->green;
956  s->colors[2] = &s->blue;
957  s->colors[3] = &s->white;
958  ff_fill_rgba_map(s->rgba_map, inlink->format);
959  } else {
960  s->colors[0] = &s->white;
961  s->colors[1] = &s->cyan;
962  s->colors[2] = &s->magenta;
963  s->colors[3] = &s->white;
964  s->rgba_map[0] = 0;
965  s->rgba_map[1] = 1;
966  s->rgba_map[2] = 2;
967  s->rgba_map[3] = 3;
968  }
969 
970  if (s->draw.desc->comp[0].depth <= 8) {
971  s->pick_color = pick_color8;
972  s->draw_trace = draw_trace8;
973  } else {
974  s->pick_color = pick_color16;
975  s->draw_trace = draw_trace16;
976  }
977 
978  s->max = (1 << s->draw.desc->comp[0].depth);
979  size = hypot(inlink->w, inlink->h);
980 
981  s->values = av_calloc(size, sizeof(*s->values));
982  if (!s->values)
983  return AVERROR(ENOMEM);
984 
986 
987  return 0;
988 }
989 
990 static void draw_scope(OscilloscopeContext *s, int x0, int y0, int x1, int y1,
991  AVFrame *out, PixelValues *p, int state)
992 {
993  int dx = FFABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
994  int dy = FFABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
995  int err = (dx > dy ? dx : -dy) / 2, e2;
996 
997  for (;;) {
998  if (x0 >= 0 && y0 >= 0 && x0 < out->width && y0 < out->height) {
999  FFDrawColor color = { { 0 } };
1000  int value[4] = { 0 };
1001 
1002  s->pick_color(&s->draw, &color, out, x0, y0, value);
1003  s->values[s->nb_values].p[0] = value[0];
1004  s->values[s->nb_values].p[1] = value[1];
1005  s->values[s->nb_values].p[2] = value[2];
1006  s->values[s->nb_values].p[3] = value[3];
1007  s->nb_values++;
1008 
1009  if (s->scope) {
1010  if (s->draw.desc->comp[0].depth == 8) {
1011  if (s->draw.nb_planes == 1) {
1012  int i;
1013 
1014  for (i = 0; i < s->nb_comps; i++)
1015  out->data[0][out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i] = 255 * ((s->nb_values + state) & 1);
1016  } else {
1017  out->data[0][out->linesize[0] * y0 + x0] = 255 * ((s->nb_values + state) & 1);
1018  }
1019  } else {
1020  if (s->draw.nb_planes == 1) {
1021  int i;
1022 
1023  for (i = 0; i < s->nb_comps; i++)
1024  AV_WN16(out->data[0] + out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i, (s->max - 1) * ((s->nb_values + state) & 1));
1025  } else {
1026  AV_WN16(out->data[0] + out->linesize[0] * y0 + 2 * x0, (s->max - 1) * ((s->nb_values + state) & 1));
1027  }
1028  }
1029  }
1030  }
1031 
1032  if (x0 == x1 && y0 == y1)
1033  break;
1034 
1035  e2 = err;
1036 
1037  if (e2 >-dx) {
1038  err -= dy;
1039  x0 += sx;
1040  }
1041 
1042  if (e2 < dy) {
1043  err += dx;
1044  y0 += sy;
1045  }
1046  }
1047 }
1048 
1050 {
1051  AVFilterContext *ctx = inlink->dst;
1052  OscilloscopeContext *s = ctx->priv;
1053  AVFilterLink *outlink = ctx->outputs[0];
1054  float average[4] = { 0 };
1055  int max[4] = { 0 };
1056  int min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
1057  int i, c;
1058 
1059  s->nb_values = 0;
1060  draw_scope(s, s->x1, s->y1, s->x2, s->y2, frame, s->values, inlink->frame_count_in & 1);
1061  ff_blend_rectangle(&s->draw, &s->dark, frame->data, frame->linesize,
1062  frame->width, frame->height,
1063  s->ox, s->oy, s->width, s->height + 20 * s->statistics);
1064 
1065  if (s->grid && outlink->h >= 10) {
1066  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1067  s->ox, s->oy, s->width - 1, 1);
1068 
1069  for (i = 1; i < 5; i++) {
1070  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1071  s->ox, s->oy + i * (s->height - 1) / 4, s->width, 1);
1072  }
1073 
1074  for (i = 0; i < 10; i++) {
1075  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1076  s->ox + i * (s->width - 1) / 10, s->oy, 1, s->height);
1077  }
1078 
1079  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1080  s->ox + s->width - 1, s->oy, 1, s->height);
1081  }
1082 
1083  s->draw_trace(s, frame);
1084 
1085  for (i = 0; i < s->nb_values; i++) {
1086  for (c = 0; c < s->nb_comps; c++) {
1087  if ((1 << c) & s->components) {
1088  max[c] = FFMAX(max[c], s->values[i].p[s->rgba_map[c]]);
1089  min[c] = FFMIN(min[c], s->values[i].p[s->rgba_map[c]]);
1090  average[c] += s->values[i].p[s->rgba_map[c]];
1091  }
1092  }
1093  }
1094  for (c = 0; c < s->nb_comps; c++) {
1095  average[c] /= s->nb_values;
1096  }
1097 
1098  if (s->statistics && s->height > 10 && s->width > 280 * av_popcount(s->components)) {
1099  for (c = 0, i = 0; c < s->nb_comps; c++) {
1100  if ((1 << c) & s->components) {
1101  const char rgba[4] = { 'R', 'G', 'B', 'A' };
1102  const char yuva[4] = { 'Y', 'U', 'V', 'A' };
1103  char text[128];
1104 
1105  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]);
1106  draw_text(&s->draw, frame, &s->white, s->ox + 2 + 280 * i++, s->oy + s->height + 4, text, 0);
1107  }
1108  }
1109  }
1110 
1111  return ff_filter_frame(outlink, frame);
1112 }
1113 
1114 static int oscilloscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
1115  char *res, int res_len, int flags)
1116 {
1117  int ret;
1118 
1119  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
1120  if (ret < 0)
1121  return ret;
1122 
1124 
1125  return 0;
1126 }
1127 
1129  {
1130  .name = "default",
1131  .type = AVMEDIA_TYPE_VIDEO,
1132  .filter_frame = oscilloscope_filter_frame,
1133  .config_props = oscilloscope_config_input,
1134  .needs_writable = 1,
1135  },
1136  { NULL }
1137 };
1138 
1140  {
1141  .name = "default",
1142  .type = AVMEDIA_TYPE_VIDEO,
1143  },
1144  { NULL }
1145 };
1146 
1148  .name = "oscilloscope",
1149  .description = NULL_IF_CONFIG_SMALL("2D Video Oscilloscope."),
1150  .priv_size = sizeof(OscilloscopeContext),
1151  .priv_class = &oscilloscope_class,
1158 };
OscilloscopeContext::o
float o
Definition: vf_datascope.c:765
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:97
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
PixscopeContext::colors
FFDrawColor * colors[4]
Definition: vf_datascope.c:486
td
#define td
Definition: regdef.h:70
FFDrawColor
Definition: drawutils.h:49
DatascopeContext::components
int components
Definition: vf_datascope.c:39
DatascopeContext::x
int x
Definition: vf_datascope.c:35
reverse_color8
static void reverse_color8(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:144
pixscope_inputs
static const AVFilterPad pixscope_inputs[]
Definition: vf_datascope.c:723
OscilloscopeContext::oy
int oy
Definition: vf_datascope.c:772
filter_mono
static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:266
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:766
PixscopeContext::x
int x
Definition: vf_datascope.c:472
out
FILE * out
Definition: movenc.c:54
pixscope_outputs
static const AVFilterPad pixscope_outputs[]
Definition: vf_datascope.c:733
DatascopeContext::dformat
int dformat
Definition: vf_datascope.c:37
PixscopeContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_datascope.c:478
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:711
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:176
OscilloscopeContext::theight
float theight
Definition: vf_datascope.c:764
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
FFDrawColor::comp
union FFDrawColor::@200 comp[MAX_PLANES]
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:112
DatascopeContext::gray
FFDrawColor gray
Definition: vf_datascope.c:49
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
PixscopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:479
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:38
FFDrawColor::u16
uint16_t u16[8]
Definition: drawutils.h:53
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
AVOption
AVOption.
Definition: opt.h:247
OscilloscopeContext::ox
int ox
Definition: vf_datascope.c:772
FFDrawColor::rgba
uint8_t rgba[4]
Definition: drawutils.h:50
DatascopeContext::opacity
float opacity
Definition: vf_datascope.c:40
PixscopeContext::dark
FFDrawColor dark
Definition: vf_datascope.c:480
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
PixscopeContext::y
int y
Definition: vf_datascope.c:472
OFFSET
#define OFFSET(x)
Definition: vf_datascope.c:56
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:799
av_popcount
#define av_popcount
Definition: common.h:150
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:108
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1565
OscilloscopeContext::max
int max
Definition: vf_datascope.c:775
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:783
OscilloscopeContext::draw_trace
void(* draw_trace)(struct OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:796
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2580
OscilloscopeContext::gray
FFDrawColor gray
Definition: vf_datascope.c:789
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:348
ThreadData::yoff
int yoff
Definition: vf_datascope.c:173
DatascopeContext::chars
int chars
Definition: vf_datascope.c:44
OscilloscopeContext::y1
int y1
Definition: vf_datascope.c:771
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:421
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:526
PixscopeContext::is_rgb
int is_rgb
Definition: vf_datascope.c:477
PixscopeContext::blue
FFDrawColor blue
Definition: vf_datascope.c:484
DatascopeContext::reverse_color
void(* reverse_color)(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:52
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
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
update_oscilloscope
static void update_oscilloscope(AVFilterContext *ctx)
Definition: vf_datascope.c:912
PixscopeContext::values
uint16_t values[4][80][80]
Definition: vf_datascope.c:488
OscilloscopeContext::ty
float ty
Definition: vf_datascope.c:761
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:469
filter_color
static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:223
OscilloscopeContext::y2
int y2
Definition: vf_datascope.c:771
DatascopeContext::filter
int(* filter)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:53
OscilloscopeContext::ypos
float ypos
Definition: vf_datascope.c:760
width
#define width
intreadwrite.h
oscilloscope_uninit
static void oscilloscope_uninit(AVFilterContext *ctx)
Definition: vf_datascope.c:820
s
#define s(width, name)
Definition: cbs_vp9.c:257
PixelValues::p
uint16_t p[4]
Definition: vf_datascope.c:754
PixscopeContext::wy
float wy
Definition: vf_datascope.c:468
FFDrawContext::vsub
uint8_t vsub[MAX_PLANES]
Definition: drawutils.h:42
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_datascope.c:379
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2033
inputs
static const AVFilterPad inputs[]
Definition: vf_datascope.c:433
OscilloscopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:776
PixscopeContext::red
FFDrawColor red
Definition: vf_datascope.c:485
oscilloscope_outputs
static const AVFilterPad oscilloscope_outputs[]
Definition: vf_datascope.c:1139
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:773
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
Definition: drawutils.c:82
pick_color16
static void pick_color16(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:126
DatascopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:45
PixscopeContext::green
FFDrawColor green
Definition: vf_datascope.c:483
OscilloscopeContext::nb_values
int nb_values
Definition: vf_datascope.c:792
reverse_color16
static void reverse_color16(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:156
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_datascope.c:80
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:65
POFFSET
#define POFFSET(x)
Definition: vf_datascope.c:493
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:537
PixscopeContext::white
FFDrawColor white
Definition: vf_datascope.c:482
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
state
static struct @317 state
OscilloscopeContext::magenta
FFDrawColor magenta
Definition: vf_datascope.c:788
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
Definition: opt.h:234
parseutils.h
DatascopeContext
Definition: vf_datascope.c:32
OscilloscopeContext::colors
FFDrawColor * colors[4]
Definition: vf_datascope.c:790
DatascopeContext::oh
int oh
Definition: vf_datascope.c:34
datascope_options
static const AVOption datascope_options[]
Definition: vf_datascope.c:60
oscilloscope_options
static const AVOption oscilloscope_options[]
Definition: vf_datascope.c:801
PixscopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:475
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:51
OscilloscopeContext::tx
float tx
Definition: vf_datascope.c:761
draw_trace8
static void draw_trace8(OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:875
PixscopeContext::o
float o
Definition: vf_datascope.c:470
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:786
draw_trace16
static void draw_trace16(OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:894
DatascopeContext::ow
int ow
Definition: vf_datascope.c:34
OscilloscopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:777
PixscopeContext::wh
int wh
Definition: vf_datascope.c:473
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:116
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_datascope.c:308
DatascopeContext::mode
int mode
Definition: vf_datascope.c:36
FLAGS
#define FLAGS
Definition: vf_datascope.c:57
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:136
ThreadData::PP
int PP
Definition: vf_datascope.c:173
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:349
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:678
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:1114
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
W
@ W
Definition: vf_addroi.c:26
outputs
static const AVFilterPad outputs[]
Definition: vf_datascope.c:443
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:85
oscilloscope_inputs
static const AVFilterPad oscilloscope_inputs[]
Definition: vf_datascope.c:1128
X
@ X
Definition: vf_addroi.c:26
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:222
OscilloscopeContext::cyan
FFDrawColor cyan
Definition: vf_datascope.c:787
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:566
height
#define height
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:795
OscilloscopeContext::size
float size
Definition: vf_datascope.c:762
xga_font_data.h
OscilloscopeContext::x1
int x1
Definition: vf_datascope.c:771
DatascopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:43
M_PI
#define M_PI
Definition: mathematics.h:52
Y
#define Y
Definition: boxblur.h:37
ff_vf_pixscope
const AVFilter ff_vf_pixscope
Definition: vf_datascope.c:741
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:227
OscilloscopeContext::scope
int scope
Definition: vf_datascope.c:769
OscilloscopeContext
Definition: vf_datascope.c:757
i
int i
Definition: input.c:406
OscilloscopeContext::black
FFDrawColor black
Definition: vf_datascope.c:782
PixscopeContext
Definition: vf_datascope.c:464
OscilloscopeContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_datascope.c:779
SQR
#define SQR(x)
Definition: vf_datascope.c:564
DatascopeContext::white
FFDrawColor white
Definition: vf_datascope.c:47
OscilloscopeContext::tilt
float tilt
Definition: vf_datascope.c:763
DatascopeContext::y
int y
Definition: vf_datascope.c:35
OscilloscopeContext::statistics
int statistics
Definition: vf_datascope.c:768
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:635
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:784
OscilloscopeContext::xpos
float xpos
Definition: vf_datascope.c:760
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
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
DatascopeContext::black
FFDrawColor black
Definition: vf_datascope.c:48
DatascopeContext::axis
int axis
Definition: vf_datascope.c:38
FFDrawContext
Definition: drawutils.h:35
OscilloscopeContext::dark
FFDrawColor dark
Definition: vf_datascope.c:781
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
FLAGSR
#define FLAGSR
Definition: vf_datascope.c:58
OscilloscopeContext::is_rgb
int is_rgb
Definition: vf_datascope.c:778
DatascopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:42
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:135
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:490
ThreadData::xoff
int xoff
Definition: vf_datascope.c:173
ret
ret
Definition: filter_design.txt:187
PixscopeContext::black
FFDrawColor black
Definition: vf_datascope.c:481
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:780
ff_vf_oscilloscope
const AVFilter ff_vf_oscilloscope
Definition: vf_datascope.c:1147
OscilloscopeContext::twidth
float twidth
Definition: vf_datascope.c:764
AVFrame::height
int height
Definition: frame.h:361
OscilloscopeContext::grid
int grid
Definition: vf_datascope.c:767
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:476
mode
mode
Definition: ebur128.h:83
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
avfilter.h
PixscopeContext::xpos
float xpos
Definition: vf_datascope.c:467
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
PixscopeContext::ypos
float ypos
Definition: vf_datascope.c:467
AVFilterContext
An instance of a filter.
Definition: avfilter.h:333
PixscopeContext::h
int h
Definition: vf_datascope.c:469
OscilloscopeContext::width
int width
Definition: vf_datascope.c:773
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:452
ThreadData::in
AVFrame * in
Definition: af_adenorm.c:223
PixscopeContext::wx
float wx
Definition: vf_datascope.c:468
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:990
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:410
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
draw_line
static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1, AVFrame *out, FFDrawColor *color)
Definition: vf_datascope.c:827
pixscope_options
static const AVOption pixscope_options[]
Definition: vf_datascope.c:495
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:508
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:33
DatascopeContext::yellow
FFDrawColor yellow
Definition: vf_datascope.c:46
OscilloscopeContext::blue
FFDrawColor blue
Definition: vf_datascope.c:785
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:793
drawutils.h
OscilloscopeContext::x2
int x2
Definition: vf_datascope.c:771
int
int
Definition: ffmpeg_filter.c:156
PixelValues
Definition: vf_datascope.c:753
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
snprintf
#define snprintf
Definition: snprintf.h:34
oscilloscope_filter_frame
static int oscilloscope_filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: vf_datascope.c:1049
PixscopeContext::ww
int ww
Definition: vf_datascope.c:473
oscilloscope_config_input
static int oscilloscope_config_input(AVFilterLink *inlink)
Definition: vf_datascope.c:935
min
float min
Definition: vorbis_enc_data.h:429
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:372