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