FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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  AVFilterContext *ctx = inlink->dst;
386  DatascopeContext *s = ctx->priv;
387 
388  uint8_t alpha = s->opacity * 255;
389  int ret;
390 
391  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
392  ret = ff_draw_init2(&s->draw, inlink->format, inlink->colorspace, inlink->color_range, 0);
393  if (ret < 0) {
394  av_log(ctx, AV_LOG_ERROR, "Failed to initialize FFDrawContext\n");
395  return ret;
396  }
397  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
398  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, alpha} );
399  ff_draw_color(&s->draw, &s->yellow, (uint8_t[]){ 255, 255, 0, 255} );
400  ff_draw_color(&s->draw, &s->gray, (uint8_t[]){ 77, 77, 77, 255} );
401  s->chars = (s->draw.desc->comp[0].depth + 7) / 8 * 2 + s->dformat;
402  s->nb_comps = s->draw.desc->nb_components;
403 
404  switch (s->mode) {
405  case 0: s->filter = filter_mono; break;
406  case 1: s->filter = filter_color; break;
407  case 2: s->filter = filter_color2; break;
408  }
409 
410  if (s->draw.desc->comp[0].depth <= 8) {
411  s->pick_color = pick_color8;
412  s->reverse_color = reverse_color8;
413  } else {
414  s->pick_color = pick_color16;
415  s->reverse_color = reverse_color16;
416  }
417 
418  return 0;
419 }
420 
421 static int config_output(AVFilterLink *outlink)
422 {
423  DatascopeContext *s = outlink->src->priv;
424 
425  outlink->h = s->oh;
426  outlink->w = s->ow;
427  outlink->sample_aspect_ratio = (AVRational){1,1};
428 
429  return 0;
430 }
431 
432 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
433  char *res, int res_len, int flags)
434 {
435  int ret;
436 
437  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
438  if (ret < 0)
439  return ret;
440 
441  return config_input(ctx->inputs[0]);
442 }
443 
444 static const AVFilterPad inputs[] = {
445  {
446  .name = "default",
447  .type = AVMEDIA_TYPE_VIDEO,
448  .filter_frame = filter_frame,
449  .config_props = config_input,
450  },
451 };
452 
453 static const AVFilterPad outputs[] = {
454  {
455  .name = "default",
456  .type = AVMEDIA_TYPE_VIDEO,
457  .config_props = config_output,
458  },
459 };
460 
462  .p.name = "datascope",
463  .p.description = NULL_IF_CONFIG_SMALL("Video data analysis."),
464  .p.priv_class = &datascope_class,
465  .p.flags = AVFILTER_FLAG_SLICE_THREADS,
466  .priv_size = sizeof(DatascopeContext),
470  .process_command = process_command,
471 };
472 
473 typedef struct PixscopeContext {
474  const AVClass *class;
475 
476  float xpos, ypos;
477  float wx, wy;
478  int w, h;
479  float o;
480 
481  int x, y;
482  int ww, wh;
483 
485  int nb_comps;
486  int is_rgb;
487  uint8_t rgba_map[4];
496 
497  uint16_t values[4][80][80];
498 
499  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
501 
502 #define POFFSET(x) offsetof(PixscopeContext, x)
503 
504 static const AVOption pixscope_options[] = {
505  { "x", "set scope x offset", POFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
506  { "y", "set scope y offset", POFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
507  { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGSR },
508  { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGSR },
509  { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
510  { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGSR },
511  { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGSR },
512  { NULL }
513 };
514 
515 AVFILTER_DEFINE_CLASS(pixscope);
516 
518 {
519  AVFilterContext *ctx = inlink->dst;
520  PixscopeContext *s = ctx->priv;
521  int ret;
522 
523  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
524  ret = ff_draw_init(&s->draw, inlink->format, 0);
525  if (ret < 0) {
526  av_log(ctx, AV_LOG_ERROR, "Failed to initialize FFDrawContext\n");
527  return ret;
528  }
529  ff_draw_color(&s->draw, &s->dark, (uint8_t[]){ 0, 0, 0, s->o * 255} );
530  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, 255} );
531  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
532  ff_draw_color(&s->draw, &s->green, (uint8_t[]){ 0, 255, 0, 255} );
533  ff_draw_color(&s->draw, &s->blue, (uint8_t[]){ 0, 0, 255, 255} );
534  ff_draw_color(&s->draw, &s->red, (uint8_t[]){ 255, 0, 0, 255} );
535  s->nb_comps = s->draw.desc->nb_components;
536  s->is_rgb = s->draw.desc->flags & AV_PIX_FMT_FLAG_RGB;
537 
538  if (s->is_rgb) {
539  s->colors[0] = &s->red;
540  s->colors[1] = &s->green;
541  s->colors[2] = &s->blue;
542  s->colors[3] = &s->white;
543  ff_fill_rgba_map(s->rgba_map, inlink->format);
544  } else {
545  s->colors[0] = &s->white;
546  s->colors[1] = &s->blue;
547  s->colors[2] = &s->red;
548  s->colors[3] = &s->white;
549  s->rgba_map[0] = 0;
550  s->rgba_map[1] = 1;
551  s->rgba_map[2] = 2;
552  s->rgba_map[3] = 3;
553  }
554 
555  if (s->draw.desc->comp[0].depth <= 8) {
556  s->pick_color = pick_color8;
557  } else {
558  s->pick_color = pick_color16;
559  }
560 
561  if (inlink->w < 640 || inlink->h < 480) {
562  av_log(inlink->dst, AV_LOG_ERROR, "min supported resolution is 640x480\n");
563  return AVERROR(EINVAL);
564  }
565 
566  s->ww = 300;
567  s->wh = 300 * 1.6;
568  s->x = s->xpos * (inlink->w - 1);
569  s->y = s->ypos * (inlink->h - 1);
570  if (s->x + s->w >= inlink->w || s->y + s->h >= inlink->h) {
571  av_log(inlink->dst, AV_LOG_WARNING, "scope position is out of range, clipping\n");
572  s->x = FFMIN(s->x, inlink->w - s->w);
573  s->y = FFMIN(s->y, inlink->h - s->h);
574  }
575 
576  return 0;
577 }
578 
579 #define SQR(x) ((x)*(x))
580 
582 {
583  AVFilterContext *ctx = inlink->dst;
584  PixscopeContext *s = ctx->priv;
585  AVFilterLink *outlink = ctx->outputs[0];
586  AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height);
587  int max[4] = { 0 }, min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
588  float average[4] = { 0 };
589  double std[4] = { 0 }, rms[4] = { 0 };
590  const char rgba[4] = { 'R', 'G', 'B', 'A' };
591  const char yuva[4] = { 'Y', 'U', 'V', 'A' };
592  int x, y, X, Y, i, w, h;
593  char text[128];
594 
595  if (!out) {
596  av_frame_free(&in);
597  return AVERROR(ENOMEM);
598  }
600  av_frame_copy(out, in);
601 
602  w = s->ww / s->w;
603  h = s->ww / s->h;
604 
605  if (s->wx >= 0) {
606  X = (in->width - s->ww) * s->wx;
607  } else {
608  X = (in->width - s->ww) * -s->wx;
609  }
610  if (s->wy >= 0) {
611  Y = (in->height - s->wh) * s->wy;
612  } else {
613  Y = (in->height - s->wh) * -s->wy;
614  }
615 
616  if (s->wx < 0) {
617  if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) &&
618  s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) {
619  X = (in->width - s->ww) * (1 + s->wx);
620  }
621  }
622 
623  if (s->wy < 0) {
624  if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) &&
625  s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) {
626  Y = (in->height - s->wh) * (1 + s->wy);
627  }
628  }
629 
630  ff_blend_rectangle(&s->draw, &s->dark, out->data, out->linesize,
631  out->width, out->height,
632  X,
633  Y,
634  s->ww,
635  s->wh);
636 
637  for (y = 0; y < s->h; y++) {
638  for (x = 0; x < s->w; x++) {
639  FFDrawColor color = { { 0 } };
640  int value[4] = { 0 };
641 
642  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
643  ff_fill_rectangle(&s->draw, &color, out->data, out->linesize,
644  x * w + (s->ww - 4 - (s->w * w)) / 2 + X, y * h + 2 + Y, w, h);
645  for (i = 0; i < 4; i++) {
646  s->values[i][x][y] = value[i];
647  rms[i] += (double)value[i] * (double)value[i];
648  average[i] += value[i];
649  min[i] = FFMIN(min[i], value[i]);
650  max[i] = FFMAX(max[i], value[i]);
651  }
652  }
653  }
654 
655  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
656  out->width, out->height,
657  s->x - 2, s->y - 2, s->w + 4, 1);
658 
659  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
660  out->width, out->height,
661  s->x - 1, s->y - 1, s->w + 2, 1);
662 
663  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
664  out->width, out->height,
665  s->x - 1, s->y - 1, 1, s->h + 2);
666 
667  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
668  out->width, out->height,
669  s->x - 2, s->y - 2, 1, s->h + 4);
670 
671  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
672  out->width, out->height,
673  s->x - 1, s->y + 1 + s->h, s->w + 3, 1);
674 
675  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
676  out->width, out->height,
677  s->x - 2, s->y + 2 + s->h, s->w + 4, 1);
678 
679  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
680  out->width, out->height,
681  s->x + 1 + s->w, s->y - 1, 1, s->h + 2);
682 
683  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
684  out->width, out->height,
685  s->x + 2 + s->w, s->y - 2, 1, s->h + 5);
686 
687  for (i = 0; i < 4; i++) {
688  rms[i] /= s->w * s->h;
689  rms[i] = sqrt(rms[i]);
690  average[i] /= s->w * s->h;
691  }
692 
693  for (y = 0; y < s->h; y++) {
694  for (x = 0; x < s->w; x++) {
695  for (i = 0; i < 4; i++)
696  std[i] += SQR(s->values[i][x][y] - average[i]);
697  }
698  }
699 
700  for (i = 0; i < 4; i++) {
701  std[i] /= s->w * s->h;
702  std[i] = sqrt(std[i]);
703  }
704 
705  snprintf(text, sizeof(text), "CH AVG MIN MAX RMS\n");
706  draw_text(&s->draw, out, &s->white, X + 28, Y + s->ww + 5, text, 0);
707  for (i = 0; i < s->nb_comps; i++) {
708  int c = s->rgba_map[i];
709 
710  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]);
711  draw_text(&s->draw, out, s->colors[i], X + 28, Y + s->ww + 15 * (i + 1), text, 0);
712  }
713  snprintf(text, sizeof(text), "CH STD\n");
714  draw_text(&s->draw, out, &s->white, X + 28, Y + s->ww + 15 * (0 + 5), text, 0);
715  for (i = 0; i < s->nb_comps; i++) {
716  int c = s->rgba_map[i];
717 
718  snprintf(text, sizeof(text), "%c %07.2f\n", s->is_rgb ? rgba[i] : yuva[i], std[c]);
719  draw_text(&s->draw, out, s->colors[i], X + 28, Y + s->ww + 15 * (i + 6), text, 0);
720  }
721 
722  av_frame_free(&in);
723  return ff_filter_frame(outlink, out);
724 }
725 
726 static int pixscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
727  char *res, int res_len, int flags)
728 {
729  int ret;
730 
731  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
732  if (ret < 0)
733  return ret;
734 
735  return pixscope_config_input(ctx->inputs[0]);
736 }
737 
738 static const AVFilterPad pixscope_inputs[] = {
739  {
740  .name = "default",
741  .type = AVMEDIA_TYPE_VIDEO,
742  .filter_frame = pixscope_filter_frame,
743  .config_props = pixscope_config_input,
744  },
745 };
746 
748  .p.name = "pixscope",
749  .p.description = NULL_IF_CONFIG_SMALL("Pixel data analysis."),
750  .p.priv_class = &pixscope_class,
752  .priv_size = sizeof(PixscopeContext),
756  .process_command = pixscope_process_command,
757 };
758 
759 typedef struct PixelValues {
760  uint16_t p[4];
761 } PixelValues;
762 
763 typedef struct OscilloscopeContext {
764  const AVClass *class;
765 
766  float xpos, ypos;
767  float tx, ty;
768  float size;
769  float tilt;
770  float theight, twidth;
771  float o;
773  int grid;
775  int scope;
776 
777  int x1, y1, x2, y2;
778  int ox, oy;
779  int height, width;
780 
781  int max;
783  int nb_comps;
784  int is_rgb;
785  uint8_t rgba_map[4];
797 
800 
801  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
804 
805 #define OOFFSET(x) offsetof(OscilloscopeContext, x)
806 
807 static const AVOption oscilloscope_options[] = {
808  { "x", "set scope x position", OOFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
809  { "y", "set scope y position", OOFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
810  { "s", "set scope size", OOFFSET(size), AV_OPT_TYPE_FLOAT, {.dbl=0.8}, 0, 1, FLAGSR },
811  { "t", "set scope tilt", OOFFSET(tilt), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
812  { "o", "set trace opacity", OOFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.8}, 0, 1, FLAGSR },
813  { "tx", "set trace x position", OOFFSET(tx), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGSR },
814  { "ty", "set trace y position", OOFFSET(ty), AV_OPT_TYPE_FLOAT, {.dbl=0.9}, 0, 1, FLAGSR },
815  { "tw", "set trace width", OOFFSET(twidth), AV_OPT_TYPE_FLOAT, {.dbl=0.8},.1, 1, FLAGSR },
816  { "th", "set trace height", OOFFSET(theight), AV_OPT_TYPE_FLOAT, {.dbl=0.3},.1, 1, FLAGSR },
817  { "c", "set components to trace", OOFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, FLAGSR },
818  { "g", "draw trace grid", OOFFSET(grid), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
819  { "st", "draw statistics", OOFFSET(statistics), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
820  { "sc", "draw scope", OOFFSET(scope), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGSR },
821  { NULL }
822 };
823 
824 AVFILTER_DEFINE_CLASS(oscilloscope);
825 
827 {
828  OscilloscopeContext *s = ctx->priv;
829 
830  av_freep(&s->values);
831 }
832 
833 static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1,
835 {
836  int dx = FFABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
837  int dy = FFABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
838  int err = (dx > dy ? dx : -dy) / 2, e2;
839  int p, i;
840 
841  for (;;) {
842  if (x0 >= 0 && y0 >= 0 && x0 < out->width && y0 < out->height) {
843  for (p = 0; p < draw->nb_planes; p++) {
844  if (draw->desc->comp[p].depth == 8) {
845  if (draw->nb_planes == 1) {
846  for (i = 0; i < draw->desc->nb_components; i++) {
847  out->data[0][y0 * out->linesize[0] + x0 * draw->pixelstep[0] + i] = color->comp[0].u8[i];
848  }
849  } else {
850  out->data[p][out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p])] = color->comp[p].u8[0];
851  }
852  } else {
853  if (draw->nb_planes == 1) {
854  for (i = 0; i < draw->desc->nb_components; i++) {
855  AV_WN16(out->data[0] + y0 * out->linesize[0] + (x0 * draw->pixelstep[0] + i), color->comp[0].u16[i]);
856  }
857  } else {
858  AV_WN16(out->data[p] + out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p]) * 2, color->comp[p].u16[0]);
859  }
860  }
861  }
862  }
863 
864  if (x0 == x1 && y0 == y1)
865  break;
866 
867  e2 = err;
868 
869  if (e2 >-dx) {
870  err -= dy;
871  x0 += sx;
872  }
873 
874  if (e2 < dy) {
875  err += dx;
876  y0 += sy;
877  }
878  }
879 }
880 
882 {
883  int i, c;
884 
885  for (i = 1; i < s->nb_values; i++) {
886  for (c = 0; c < s->nb_comps; c++) {
887  if ((1 << c) & s->components) {
888  int x = i * s->width / s->nb_values;
889  int px = (i - 1) * s->width / s->nb_values;
890  int py = s->height - s->values[i-1].p[s->rgba_map[c]] * s->height / 256;
891  int y = s->height - s->values[i].p[s->rgba_map[c]] * s->height / 256;
892 
893  draw_line(&s->draw, s->ox + x, s->oy + y, s->ox + px, s->oy + py, frame, s->colors[c]);
894  }
895  }
896  }
897 }
898 
899 
901 {
902  int i, c;
903 
904  for (i = 1; i < s->nb_values; i++) {
905  for (c = 0; c < s->nb_comps; c++) {
906  if ((1 << c) & s->components) {
907  int x = i * s->width / s->nb_values;
908  int px = (i - 1) * s->width / s->nb_values;
909  int py = s->height - s->values[i-1].p[s->rgba_map[c]] * s->height / s->max;
910  int y = s->height - s->values[i].p[s->rgba_map[c]] * s->height / s->max;
911 
912  draw_line(&s->draw, s->ox + x, s->oy + y, s->ox + px, s->oy + py, frame, s->colors[c]);
913  }
914  }
915  }
916 }
917 
919 {
920  OscilloscopeContext *s = ctx->priv;
921  AVFilterLink *inlink = ctx->inputs[0];
922  int cx, cy, size;
923  double tilt;
924 
925  ff_draw_color(&s->draw, &s->dark, (uint8_t[]){ 0, 0, 0, s->o * 255} );
926  s->height = s->theight * inlink->h;
927  s->width = s->twidth * inlink->w;
928  size = hypot(inlink->w, inlink->h);
929  size *= s->size;
930  tilt = (s->tilt - 0.5) * M_PI;
931  cx = s->xpos * (inlink->w - 1);
932  cy = s->ypos * (inlink->h - 1);
933  s->x1 = cx - size / 2.0 * cos(tilt);
934  s->x2 = cx + size / 2.0 * cos(tilt);
935  s->y1 = cy - size / 2.0 * sin(tilt);
936  s->y2 = cy + size / 2.0 * sin(tilt);
937  s->ox = (inlink->w - s->width) * s->tx;
938  s->oy = (inlink->h - s->height) * s->ty;
939 }
940 
942 {
943  AVFilterContext *ctx = inlink->dst;
944  OscilloscopeContext *s = ctx->priv;
945  int size;
946  int ret;
947 
948  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
949  ret = ff_draw_init(&s->draw, inlink->format, 0);
950  if (ret < 0) {
951  av_log(ctx, AV_LOG_ERROR, "Failed to initialize FFDrawContext\n");
952  return ret;
953  }
954  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, 255} );
955  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
956  ff_draw_color(&s->draw, &s->green, (uint8_t[]){ 0, 255, 0, 255} );
957  ff_draw_color(&s->draw, &s->blue, (uint8_t[]){ 0, 0, 255, 255} );
958  ff_draw_color(&s->draw, &s->red, (uint8_t[]){ 255, 0, 0, 255} );
959  ff_draw_color(&s->draw, &s->cyan, (uint8_t[]){ 0, 255, 255, 255} );
960  ff_draw_color(&s->draw, &s->magenta, (uint8_t[]){ 255, 0, 255, 255} );
961  ff_draw_color(&s->draw, &s->gray, (uint8_t[]){ 128, 128, 128, 255} );
962  s->nb_comps = s->draw.desc->nb_components;
963  s->is_rgb = s->draw.desc->flags & AV_PIX_FMT_FLAG_RGB;
964 
965  if (s->is_rgb) {
966  s->colors[0] = &s->red;
967  s->colors[1] = &s->green;
968  s->colors[2] = &s->blue;
969  s->colors[3] = &s->white;
970  ff_fill_rgba_map(s->rgba_map, inlink->format);
971  } else {
972  s->colors[0] = &s->white;
973  s->colors[1] = &s->cyan;
974  s->colors[2] = &s->magenta;
975  s->colors[3] = &s->white;
976  s->rgba_map[0] = 0;
977  s->rgba_map[1] = 1;
978  s->rgba_map[2] = 2;
979  s->rgba_map[3] = 3;
980  }
981 
982  if (s->draw.desc->comp[0].depth <= 8) {
983  s->pick_color = pick_color8;
984  s->draw_trace = draw_trace8;
985  } else {
986  s->pick_color = pick_color16;
987  s->draw_trace = draw_trace16;
988  }
989 
990  s->max = (1 << s->draw.desc->comp[0].depth);
991  size = hypot(inlink->w, inlink->h);
992 
993  s->values = av_calloc(size, sizeof(*s->values));
994  if (!s->values)
995  return AVERROR(ENOMEM);
996 
998 
999  return 0;
1000 }
1001 
1002 static void draw_scope(OscilloscopeContext *s, int x0, int y0, int x1, int y1,
1003  AVFrame *out, PixelValues *p, int state)
1004 {
1005  int dx = FFABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
1006  int dy = FFABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
1007  int err = (dx > dy ? dx : -dy) / 2, e2;
1008 
1009  for (;;) {
1010  if (x0 >= 0 && y0 >= 0 && x0 < out->width && y0 < out->height) {
1011  FFDrawColor color = { { 0 } };
1012  int value[4] = { 0 };
1013 
1014  s->pick_color(&s->draw, &color, out, x0, y0, value);
1015  s->values[s->nb_values].p[0] = value[0];
1016  s->values[s->nb_values].p[1] = value[1];
1017  s->values[s->nb_values].p[2] = value[2];
1018  s->values[s->nb_values].p[3] = value[3];
1019  s->nb_values++;
1020 
1021  if (s->scope) {
1022  if (s->draw.desc->comp[0].depth == 8) {
1023  if (s->draw.nb_planes == 1) {
1024  int i;
1025 
1026  for (i = 0; i < s->nb_comps; i++)
1027  out->data[0][out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i] = 255 * ((s->nb_values + state) & 1);
1028  } else {
1029  out->data[0][out->linesize[0] * y0 + x0] = 255 * ((s->nb_values + state) & 1);
1030  }
1031  } else {
1032  if (s->draw.nb_planes == 1) {
1033  int i;
1034 
1035  for (i = 0; i < s->nb_comps; i++)
1036  AV_WN16(out->data[0] + out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i, (s->max - 1) * ((s->nb_values + state) & 1));
1037  } else {
1038  AV_WN16(out->data[0] + out->linesize[0] * y0 + 2 * x0, (s->max - 1) * ((s->nb_values + state) & 1));
1039  }
1040  }
1041  }
1042  }
1043 
1044  if (x0 == x1 && y0 == y1)
1045  break;
1046 
1047  e2 = err;
1048 
1049  if (e2 >-dx) {
1050  err -= dy;
1051  x0 += sx;
1052  }
1053 
1054  if (e2 < dy) {
1055  err += dx;
1056  y0 += sy;
1057  }
1058  }
1059 }
1060 
1062 {
1064  AVFilterContext *ctx = inlink->dst;
1065  OscilloscopeContext *s = ctx->priv;
1066  AVFilterLink *outlink = ctx->outputs[0];
1067  float average[4] = { 0 };
1068  int max[4] = { 0 };
1069  int min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
1070  int i, c;
1071 
1072  s->nb_values = 0;
1073  draw_scope(s, s->x1, s->y1, s->x2, s->y2, frame, s->values, inl->frame_count_in & 1);
1074  ff_blend_rectangle(&s->draw, &s->dark, frame->data, frame->linesize,
1075  frame->width, frame->height,
1076  s->ox, s->oy, s->width, s->height + 20 * s->statistics);
1077 
1078  if (s->grid && outlink->h >= 10) {
1079  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1080  s->ox, s->oy, s->width - 1, 1);
1081 
1082  for (i = 1; i < 5; i++) {
1083  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1084  s->ox, s->oy + i * (s->height - 1) / 4, s->width, 1);
1085  }
1086 
1087  for (i = 0; i < 10; i++) {
1088  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1089  s->ox + i * (s->width - 1) / 10, s->oy, 1, s->height);
1090  }
1091 
1092  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
1093  s->ox + s->width - 1, s->oy, 1, s->height);
1094  }
1095 
1096  s->draw_trace(s, frame);
1097 
1098  for (i = 0; i < s->nb_values; i++) {
1099  for (c = 0; c < s->nb_comps; c++) {
1100  if ((1 << c) & s->components) {
1101  max[c] = FFMAX(max[c], s->values[i].p[s->rgba_map[c]]);
1102  min[c] = FFMIN(min[c], s->values[i].p[s->rgba_map[c]]);
1103  average[c] += s->values[i].p[s->rgba_map[c]];
1104  }
1105  }
1106  }
1107  for (c = 0; c < s->nb_comps; c++) {
1108  average[c] /= s->nb_values;
1109  }
1110 
1111  if (s->statistics && s->height > 10 && s->width > 280 * av_popcount(s->components)) {
1112  for (c = 0, i = 0; c < s->nb_comps; c++) {
1113  if ((1 << c) & s->components) {
1114  const char rgba[4] = { 'R', 'G', 'B', 'A' };
1115  const char yuva[4] = { 'Y', 'U', 'V', 'A' };
1116  char text[128];
1117 
1118  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]);
1119  draw_text(&s->draw, frame, &s->white, s->ox + 2 + 280 * i++, s->oy + s->height + 4, text, 0);
1120  }
1121  }
1122  }
1123 
1124  return ff_filter_frame(outlink, frame);
1125 }
1126 
1127 static int oscilloscope_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
1128  char *res, int res_len, int flags)
1129 {
1130  int ret;
1131 
1132  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
1133  if (ret < 0)
1134  return ret;
1135 
1137 
1138  return 0;
1139 }
1140 
1142  {
1143  .name = "default",
1144  .type = AVMEDIA_TYPE_VIDEO,
1146  .filter_frame = oscilloscope_filter_frame,
1147  .config_props = oscilloscope_config_input,
1148  },
1149 };
1150 
1152  .p.name = "oscilloscope",
1153  .p.description = NULL_IF_CONFIG_SMALL("2D Video Oscilloscope."),
1154  .p.priv_class = &oscilloscope_class,
1156  .priv_size = sizeof(OscilloscopeContext),
1161  .process_command = oscilloscope_process_command,
1162 };
OscilloscopeContext::o
float o
Definition: vf_datascope.c:771
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:495
FFDrawColor
Definition: drawutils.h:51
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:147
pixscope_inputs
static const AVFilterPad pixscope_inputs[]
Definition: vf_datascope.c:738
OscilloscopeContext::oy
int oy
Definition: vf_datascope.c:778
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:772
PixscopeContext::x
int x
Definition: vf_datascope.c:481
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:487
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:726
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1078
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:770
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:70
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
DatascopeContext::gray
FFDrawColor gray
Definition: vf_datascope.c:49
mode
Definition: swscale.c:52
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
PixscopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:488
pixdesc.h
AVFrame::width
int width
Definition: frame.h:482
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:778
FFDrawColor::rgba
uint8_t rgba[4]
Definition: drawutils.h:52
DatascopeContext::opacity
float opacity
Definition: vf_datascope.c:40
ff_vf_datascope
const FFFilter ff_vf_datascope
Definition: vf_datascope.c:461
PixscopeContext::dark
FFDrawColor dark
Definition: vf_datascope.c:489
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:481
OFFSET
#define OFFSET(x)
Definition: vf_datascope.c:56
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:203
OOFFSET
#define OOFFSET(x)
Definition: vf_datascope.c:805
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
FFDrawColor::comp
union FFDrawColor::@323 comp[MAX_PLANES]
OscilloscopeContext::max
int max
Definition: vf_datascope.c:781
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:431
D
D(D(float, sse)
Definition: rematrix_init.c:30
formats.h
OscilloscopeContext::white
FFDrawColor white
Definition: vf_datascope.c:789
OscilloscopeContext::draw_trace
void(* draw_trace)(struct OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:802
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3381
OscilloscopeContext::gray
FFDrawColor gray
Definition: vf_datascope.c:795
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
Definition: mpeg12dec.c:1720
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:272
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:777
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:432
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:551
PixscopeContext::is_rgb
int is_rgb
Definition: vf_datascope.c:486
PixscopeContext::blue
FFDrawColor blue
Definition: vf_datascope.c:493
DatascopeContext::reverse_color
void(* reverse_color)(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:52
X
@ X
Definition: vf_addroi.c:27
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:918
PixscopeContext::values
uint16_t values[4][80][80]
Definition: vf_datascope.c:497
OscilloscopeContext::ty
float ty
Definition: vf_datascope.c:767
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:478
FFFilter
Definition: filters.h:265
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:777
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:766
intreadwrite.h
oscilloscope_uninit
static void oscilloscope_uninit(AVFilterContext *ctx)
Definition: vf_datascope.c:826
s
#define s(width, name)
Definition: cbs_vp9.c:198
PixelValues::p
uint16_t p[4]
Definition: vf_datascope.c:760
PixscopeContext::wy
float wy
Definition: vf_datascope.c:477
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:444
filters.h
OscilloscopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:782
PixscopeContext::red
FFDrawColor red
Definition: vf_datascope.c:494
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:779
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Definition: drawutils.c:168
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:492
OscilloscopeContext::nb_values
int nb_values
Definition: vf_datascope.c:798
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:502
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:633
PixscopeContext::white
FFDrawColor white
Definition: vf_datascope.c:491
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
OscilloscopeContext::magenta
FFDrawColor magenta
Definition: vf_datascope.c:794
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:796
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:807
double
double
Definition: af_crystalizer.c:132
PixscopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:484
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:767
draw_trace8
static void draw_trace8(OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:881
PixscopeContext::o
float o
Definition: vf_datascope.c:479
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:109
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:792
draw_trace16
static void draw_trace16(OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:900
DatascopeContext::ow
int ow
Definition: vf_datascope.c:34
OscilloscopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:783
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:482
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:370
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:745
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:1127
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:97
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:368
outputs
static const AVFilterPad outputs[]
Definition: vf_datascope.c:453
size
int size
Definition: twinvq_data.h:10344
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:96
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
W
@ W
Definition: vf_addroi.c:27
oscilloscope_inputs
static const AVFilterPad oscilloscope_inputs[]
Definition: vf_datascope.c:1141
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:248
OscilloscopeContext::cyan
FFDrawColor cyan
Definition: vf_datascope.c:793
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:917
pixscope_filter_frame
static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_datascope.c:581
ff_vf_oscilloscope
const FFFilter ff_vf_oscilloscope
Definition: vf_datascope.c:1151
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:801
OscilloscopeContext::size
float size
Definition: vf_datascope.c:768
xga_font_data.h
OscilloscopeContext::x1
int x1
Definition: vf_datascope.c:777
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
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:180
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:775
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
OscilloscopeContext
Definition: vf_datascope.c:763
OscilloscopeContext::black
FFDrawColor black
Definition: vf_datascope.c:788
PixscopeContext
Definition: vf_datascope.c:473
OscilloscopeContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_datascope.c:785
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
SQR
#define SQR(x)
Definition: vf_datascope.c:579
DatascopeContext::white
FFDrawColor white
Definition: vf_datascope.c:47
OscilloscopeContext::tilt
float tilt
Definition: vf_datascope.c:769
DatascopeContext::y
int y
Definition: vf_datascope.c:35
OscilloscopeContext::statistics
int statistics
Definition: vf_datascope.c:774
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:664
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:857
OscilloscopeContext::green
FFDrawColor green
Definition: vf_datascope.c:790
OscilloscopeContext::xpos
float xpos
Definition: vf_datascope.c:766
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:787
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:784
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:173
slice_start
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition: dec.c:734
PixscopeContext::pick_color
void(* pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:499
ThreadData::xoff
int xoff
Definition: vf_datascope.c:176
ret
ret
Definition: filter_design.txt:187
PixscopeContext::black
FFDrawColor black
Definition: vf_datascope.c:490
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:786
OscilloscopeContext::twidth
float twidth
Definition: vf_datascope.c:770
AVFrame::height
int height
Definition: frame.h:482
OscilloscopeContext::grid
int grid
Definition: vf_datascope.c:773
ff_filter_execute
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: avfilter.c:1683
PixscopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:485
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:476
PixscopeContext::ypos
float ypos
Definition: vf_datascope.c:476
AVFilterContext
An instance of a filter.
Definition: avfilter.h:257
PixscopeContext::h
int h
Definition: vf_datascope.c:478
ff_vf_pixscope
const FFFilter ff_vf_pixscope
Definition: vf_datascope.c:747
OscilloscopeContext::width
int width
Definition: vf_datascope.c:779
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:150
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:269
mem.h
PixscopeContext::wx
float wx
Definition: vf_datascope.c:477
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:1002
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:421
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:833
pixscope_options
static const AVOption pixscope_options[]
Definition: vf_datascope.c:504
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:517
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:81
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:791
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:455
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:799
width
#define width
Definition: dsp.h:85
drawutils.h
OscilloscopeContext::x2
int x2
Definition: vf_datascope.c:777
state
static struct @481 state
PixelValues
Definition: vf_datascope.c:759
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:1061
PixscopeContext::ww
int ww
Definition: vf_datascope.c:482
oscilloscope_config_input
static int oscilloscope_config_input(AVFilterLink *inlink)
Definition: vf_datascope.c:941
min
float min
Definition: vorbis_enc_data.h:429
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:368