FFmpeg
vf_datascope.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/parseutils.h"
25 #include "libavutil/pixdesc.h"
27 #include "avfilter.h"
28 #include "drawutils.h"
29 #include "formats.h"
30 #include "internal.h"
31 #include "video.h"
32 
33 typedef struct DatascopeContext {
34  const AVClass *class;
35  int ow, oh;
36  int x, y;
37  int mode;
38  int axis;
39  float opacity;
40 
41  int nb_planes;
42  int nb_comps;
43  int chars;
49 
50  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
52  int (*filter)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
54 
55 #define OFFSET(x) offsetof(DatascopeContext, x)
56 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
57 
58 static const AVOption datascope_options[] = {
59  { "size", "set output size", OFFSET(ow), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, FLAGS },
60  { "s", "set output size", OFFSET(ow), AV_OPT_TYPE_IMAGE_SIZE, {.str="hd720"}, 0, 0, FLAGS },
61  { "x", "set x offset", OFFSET(x), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
62  { "y", "set y offset", OFFSET(y), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
63  { "mode", "set scope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "mode" },
64  { "mono", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" },
65  { "color", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" },
66  { "color2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "mode" },
67  { "axis", "draw column/row numbers", OFFSET(axis), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
68  { "opacity", "set background opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS },
69  { NULL }
70 };
71 
72 AVFILTER_DEFINE_CLASS(datascope);
73 
75 {
77 }
78 
80  int x0, int y0, const uint8_t *text, int vertical)
81 {
82  int x = x0;
83 
84  for (; *text; text++) {
85  if (*text == '\n') {
86  x = x0;
87  y0 += 8;
88  continue;
89  }
90  ff_blend_mask(draw, color, frame->data, frame->linesize,
91  frame->width, frame->height,
92  avpriv_cga_font + *text * 8, 1, 8, 8, 0, 0, x, y0);
93  if (vertical) {
94  x = x0;
95  y0 += 8;
96  } else {
97  x += 8;
98  }
99  }
100 }
101 
102 static void pick_color8(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
103 {
104  int p, i;
105 
106  color->rgba[3] = 255;
107  for (p = 0; p < draw->nb_planes; p++) {
108  if (draw->nb_planes == 1) {
109  for (i = 0; i < 4; i++) {
110  value[i] = in->data[0][y * in->linesize[0] + x * draw->pixelstep[0] + i];
111  color->comp[0].u8[i] = value[i];
112  }
113  } else {
114  value[p] = in->data[p][(y >> draw->vsub[p]) * in->linesize[p] + (x >> draw->hsub[p])];
115  color->comp[p].u8[0] = value[p];
116  }
117  }
118 }
119 
120 static void pick_color16(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
121 {
122  int p, i;
123 
124  color->rgba[3] = 255;
125  for (p = 0; p < draw->nb_planes; p++) {
126  if (draw->nb_planes == 1) {
127  for (i = 0; i < 4; i++) {
128  value[i] = AV_RL16(in->data[0] + y * in->linesize[0] + x * draw->pixelstep[0] + i * 2);
129  color->comp[0].u16[i] = value[i];
130  }
131  } else {
132  value[p] = AV_RL16(in->data[p] + (y >> draw->vsub[p]) * in->linesize[p] + (x >> draw->hsub[p]) * 2);
133  color->comp[p].u16[0] = value[p];
134  }
135  }
136 }
137 
139 {
140  int p;
141 
142  reverse->rgba[3] = 255;
143  for (p = 0; p < draw->nb_planes; p++) {
144  reverse->comp[p].u8[0] = color->comp[p].u8[0] > 127 ? 0 : 255;
145  reverse->comp[p].u8[1] = color->comp[p].u8[1] > 127 ? 0 : 255;
146  reverse->comp[p].u8[2] = color->comp[p].u8[2] > 127 ? 0 : 255;
147  }
148 }
149 
151 {
152  int p;
153 
154  reverse->rgba[3] = 255;
155  for (p = 0; p < draw->nb_planes; p++) {
156  const unsigned max = (1 << draw->desc->comp[p].depth) - 1;
157  const unsigned mid = (max + 1) / 2;
158 
159  reverse->comp[p].u16[0] = color->comp[p].u16[0] > mid ? 0 : max;
160  reverse->comp[p].u16[1] = color->comp[p].u16[1] > mid ? 0 : max;
161  reverse->comp[p].u16[2] = color->comp[p].u16[2] > mid ? 0 : max;
162  }
163 }
164 
165 typedef struct ThreadData {
166  AVFrame *in, *out;
167  int xoff, yoff;
168 } ThreadData;
169 
170 static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
171 {
172  DatascopeContext *s = ctx->priv;
173  AVFilterLink *outlink = ctx->outputs[0];
174  AVFilterLink *inlink = ctx->inputs[0];
175  ThreadData *td = arg;
176  AVFrame *in = td->in;
177  AVFrame *out = td->out;
178  const int xoff = td->xoff;
179  const int yoff = td->yoff;
180  const int P = FFMAX(s->nb_planes, s->nb_comps);
181  const int C = s->chars;
182  const int W = (outlink->w - xoff) / (C * 10);
183  const int H = (outlink->h - yoff) / (P * 12);
184  const char *format[2] = {"%02X\n", "%04X\n"};
185  const int slice_start = (W * jobnr) / nb_jobs;
186  const int slice_end = (W * (jobnr+1)) / nb_jobs;
187  int x, y, p;
188 
189  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
190  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
191  FFDrawColor color = { { 0 } };
192  FFDrawColor reverse = { { 0 } };
193  int value[4] = { 0 };
194 
195  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
196  s->reverse_color(&s->draw, &color, &reverse);
197  ff_fill_rectangle(&s->draw, &color, out->data, out->linesize,
198  xoff + x * C * 10, yoff + y * P * 12, C * 10, P * 12);
199 
200  for (p = 0; p < P; p++) {
201  char text[256];
202 
203  snprintf(text, sizeof(text), format[C>>2], value[p]);
204  draw_text(&s->draw, out, &reverse, xoff + x * C * 10 + 2, yoff + y * P * 12 + p * 10 + 2, text, 0);
205  }
206  }
207  }
208 
209  return 0;
210 }
211 
212 static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
213 {
214  DatascopeContext *s = ctx->priv;
215  AVFilterLink *outlink = ctx->outputs[0];
216  AVFilterLink *inlink = ctx->inputs[0];
217  ThreadData *td = arg;
218  AVFrame *in = td->in;
219  AVFrame *out = td->out;
220  const int xoff = td->xoff;
221  const int yoff = td->yoff;
222  const int P = FFMAX(s->nb_planes, s->nb_comps);
223  const int C = s->chars;
224  const int W = (outlink->w - xoff) / (C * 10);
225  const int H = (outlink->h - yoff) / (P * 12);
226  const char *format[2] = {"%02X\n", "%04X\n"};
227  const int slice_start = (W * jobnr) / nb_jobs;
228  const int slice_end = (W * (jobnr+1)) / nb_jobs;
229  int x, y, p;
230 
231  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
232  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
233  FFDrawColor color = { { 0 } };
234  int value[4] = { 0 };
235 
236  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
237 
238  for (p = 0; p < P; p++) {
239  char text[256];
240 
241  snprintf(text, sizeof(text), format[C>>2], value[p]);
242  draw_text(&s->draw, out, &color, xoff + x * C * 10 + 2, yoff + y * P * 12 + p * 10 + 2, text, 0);
243  }
244  }
245  }
246 
247  return 0;
248 }
249 
250 static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
251 {
252  DatascopeContext *s = ctx->priv;
253  AVFilterLink *outlink = ctx->outputs[0];
254  AVFilterLink *inlink = ctx->inputs[0];
255  ThreadData *td = arg;
256  AVFrame *in = td->in;
257  AVFrame *out = td->out;
258  const int xoff = td->xoff;
259  const int yoff = td->yoff;
260  const int P = FFMAX(s->nb_planes, s->nb_comps);
261  const int C = s->chars;
262  const int W = (outlink->w - xoff) / (C * 10);
263  const int H = (outlink->h - yoff) / (P * 12);
264  const char *format[2] = {"%02X\n", "%04X\n"};
265  const int slice_start = (W * jobnr) / nb_jobs;
266  const int slice_end = (W * (jobnr+1)) / nb_jobs;
267  int x, y, p;
268 
269  for (y = 0; y < H && (y + s->y < inlink->h); y++) {
270  for (x = slice_start; x < slice_end && (x + s->x < inlink->w); x++) {
271  FFDrawColor color = { { 0 } };
272  int value[4] = { 0 };
273 
274  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
275  for (p = 0; p < P; p++) {
276  char text[256];
277 
278  snprintf(text, sizeof(text), format[C>>2], value[p]);
279  draw_text(&s->draw, out, &s->white, xoff + x * C * 10 + 2, yoff + y * P * 12 + p * 10 + 2, text, 0);
280  }
281  }
282  }
283 
284  return 0;
285 }
286 
288 {
289  AVFilterContext *ctx = inlink->dst;
290  DatascopeContext *s = ctx->priv;
291  AVFilterLink *outlink = ctx->outputs[0];
292  ThreadData td = { 0 };
293  int ymaxlen = 0;
294  int xmaxlen = 0;
295  AVFrame *out;
296 
297  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
298  if (!out) {
299  av_frame_free(&in);
300  return AVERROR(ENOMEM);
301  }
302  out->pts = in->pts;
303 
304  ff_fill_rectangle(&s->draw, &s->black, out->data, out->linesize,
305  0, 0, outlink->w, outlink->h);
306 
307  if (s->axis) {
308  const int P = FFMAX(s->nb_planes, s->nb_comps);
309  const int C = s->chars;
310  int Y = outlink->h / (P * 12);
311  int X = outlink->w / (C * 10);
312  char text[256] = { 0 };
313  int x, y;
314 
315  snprintf(text, sizeof(text), "%d", s->y + Y);
316  ymaxlen = strlen(text);
317  ymaxlen *= 10;
318  snprintf(text, sizeof(text), "%d", s->x + X);
319  xmaxlen = strlen(text);
320  xmaxlen *= 10;
321 
322  Y = (outlink->h - xmaxlen) / (P * 12);
323  X = (outlink->w - ymaxlen) / (C * 10);
324 
325  for (y = 0; y < Y; y++) {
326  snprintf(text, sizeof(text), "%d", s->y + y);
327 
328  ff_fill_rectangle(&s->draw, &s->gray, out->data, out->linesize,
329  0, xmaxlen + y * P * 12 + (P + 1) * P - 2, ymaxlen, 10);
330 
331  draw_text(&s->draw, out, &s->yellow, 2, xmaxlen + y * P * 12 + (P + 1) * P, text, 0);
332  }
333 
334  for (x = 0; x < X; x++) {
335  snprintf(text, sizeof(text), "%d", s->x + x);
336 
337  ff_fill_rectangle(&s->draw, &s->gray, out->data, out->linesize,
338  ymaxlen + x * C * 10 + 2 * C - 2, 0, 10, xmaxlen);
339 
340  draw_text(&s->draw, out, &s->yellow, ymaxlen + x * C * 10 + 2 * C, 2, text, 1);
341  }
342  }
343 
344  td.in = in; td.out = out, td.yoff = xmaxlen, td.xoff = ymaxlen;
345  ctx->internal->execute(ctx, s->filter, &td, NULL, FFMIN(ff_filter_get_nb_threads(ctx), FFMAX(outlink->w / 20, 1)));
346 
347  av_frame_free(&in);
348  return ff_filter_frame(outlink, out);
349 }
350 
352 {
353  DatascopeContext *s = inlink->dst->priv;
354  uint8_t alpha = s->opacity * 255;
355 
356  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
357  ff_draw_init(&s->draw, inlink->format, 0);
358  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
359  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, alpha} );
360  ff_draw_color(&s->draw, &s->yellow, (uint8_t[]){ 255, 255, 0, 255} );
361  ff_draw_color(&s->draw, &s->gray, (uint8_t[]){ 77, 77, 77, 255} );
362  s->chars = (s->draw.desc->comp[0].depth + 7) / 8 * 2;
363  s->nb_comps = s->draw.desc->nb_components;
364 
365  switch (s->mode) {
366  case 0: s->filter = filter_mono; break;
367  case 1: s->filter = filter_color; break;
368  case 2: s->filter = filter_color2; break;
369  }
370 
371  if (s->draw.desc->comp[0].depth <= 8) {
372  s->pick_color = pick_color8;
373  s->reverse_color = reverse_color8;
374  } else {
375  s->pick_color = pick_color16;
376  s->reverse_color = reverse_color16;
377  }
378 
379  return 0;
380 }
381 
382 static int config_output(AVFilterLink *outlink)
383 {
384  DatascopeContext *s = outlink->src->priv;
385 
386  outlink->h = s->oh;
387  outlink->w = s->ow;
388  outlink->sample_aspect_ratio = (AVRational){1,1};
389 
390  return 0;
391 }
392 
393 static const AVFilterPad inputs[] = {
394  {
395  .name = "default",
396  .type = AVMEDIA_TYPE_VIDEO,
397  .filter_frame = filter_frame,
398  .config_props = config_input,
399  },
400  { NULL }
401 };
402 
403 static const AVFilterPad outputs[] = {
404  {
405  .name = "default",
406  .type = AVMEDIA_TYPE_VIDEO,
407  .config_props = config_output,
408  },
409  { NULL }
410 };
411 
413  .name = "datascope",
414  .description = NULL_IF_CONFIG_SMALL("Video data analysis."),
415  .priv_size = sizeof(DatascopeContext),
416  .priv_class = &datascope_class,
418  .inputs = inputs,
419  .outputs = outputs,
421 };
422 
423 typedef struct PixscopeContext {
424  const AVClass *class;
425 
426  float xpos, ypos;
427  float wx, wy;
428  int w, h;
429  float o;
430 
431  int x, y;
432  int ww, wh;
433 
435  int nb_comps;
436  int is_rgb;
446 
447  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
449 
450 #define POFFSET(x) offsetof(PixscopeContext, x)
451 
452 static const AVOption pixscope_options[] = {
453  { "x", "set scope x offset", POFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
454  { "y", "set scope y offset", POFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
455  { "w", "set scope width", POFFSET(w), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS },
456  { "h", "set scope height", POFFSET(h), AV_OPT_TYPE_INT, {.i64=7}, 1, 80, FLAGS },
457  { "o", "set window opacity", POFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
458  { "wx", "set window x offset", POFFSET(wx), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGS },
459  { "wy", "set window y offset", POFFSET(wy), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 1, FLAGS },
460  { NULL }
461 };
462 
463 AVFILTER_DEFINE_CLASS(pixscope);
464 
466 {
467  PixscopeContext *s = inlink->dst->priv;
468 
469  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
470  ff_draw_init(&s->draw, inlink->format, 0);
471  ff_draw_color(&s->draw, &s->dark, (uint8_t[]){ 0, 0, 0, s->o * 255} );
472  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, 255} );
473  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
474  ff_draw_color(&s->draw, &s->green, (uint8_t[]){ 0, 255, 0, 255} );
475  ff_draw_color(&s->draw, &s->blue, (uint8_t[]){ 0, 0, 255, 255} );
476  ff_draw_color(&s->draw, &s->red, (uint8_t[]){ 255, 0, 0, 255} );
477  s->nb_comps = s->draw.desc->nb_components;
478  s->is_rgb = s->draw.desc->flags & AV_PIX_FMT_FLAG_RGB;
479 
480  if (s->is_rgb) {
481  s->colors[0] = &s->red;
482  s->colors[1] = &s->green;
483  s->colors[2] = &s->blue;
484  s->colors[3] = &s->white;
485  ff_fill_rgba_map(s->rgba_map, inlink->format);
486  } else {
487  s->colors[0] = &s->white;
488  s->colors[1] = &s->blue;
489  s->colors[2] = &s->red;
490  s->colors[3] = &s->white;
491  s->rgba_map[0] = 0;
492  s->rgba_map[1] = 1;
493  s->rgba_map[2] = 2;
494  s->rgba_map[3] = 3;
495  }
496 
497  if (s->draw.desc->comp[0].depth <= 8) {
498  s->pick_color = pick_color8;
499  } else {
500  s->pick_color = pick_color16;
501  }
502 
503  if (inlink->w < 640 || inlink->h < 480) {
504  av_log(inlink->dst, AV_LOG_ERROR, "min supported resolution is 640x480\n");
505  return AVERROR(EINVAL);
506  }
507 
508  s->ww = 300;
509  s->wh = 300 * 1.6;
510  s->x = s->xpos * (inlink->w - 1);
511  s->y = s->ypos * (inlink->h - 1);
512  if (s->x + s->w >= inlink->w || s->y + s->h >= inlink->h) {
513  av_log(inlink->dst, AV_LOG_WARNING, "scope position is out of range, clipping\n");
514  s->x = FFMIN(s->x, inlink->w - s->w);
515  s->y = FFMIN(s->y, inlink->h - s->h);
516  }
517 
518  return 0;
519 }
520 
522 {
523  AVFilterContext *ctx = inlink->dst;
524  PixscopeContext *s = ctx->priv;
525  AVFilterLink *outlink = ctx->outputs[0];
526  AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height);
527  int max[4] = { 0 }, min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
528  float average[4] = { 0 };
529  double rms[4] = { 0 };
530  const char rgba[4] = { 'R', 'G', 'B', 'A' };
531  const char yuva[4] = { 'Y', 'U', 'V', 'A' };
532  int x, y, X, Y, i, w, h;
533  char text[128];
534 
535  if (!out) {
536  av_frame_free(&in);
537  return AVERROR(ENOMEM);
538  }
540  av_frame_copy(out, in);
541 
542  w = s->ww / s->w;
543  h = s->ww / s->h;
544 
545  if (s->wx >= 0) {
546  X = (in->width - s->ww) * s->wx;
547  } else {
548  X = (in->width - s->ww) * -s->wx;
549  }
550  if (s->wy >= 0) {
551  Y = (in->height - s->wh) * s->wy;
552  } else {
553  Y = (in->height - s->wh) * -s->wy;
554  }
555 
556  if (s->wx < 0) {
557  if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) &&
558  s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) {
559  X = (in->width - s->ww) * (1 + s->wx);
560  }
561  }
562 
563  if (s->wy < 0) {
564  if (s->x + s->w >= X && (s->x + s->w <= X + s->ww) &&
565  s->y + s->h >= Y && (s->y + s->h <= Y + s->wh)) {
566  Y = (in->height - s->wh) * (1 + s->wy);
567  }
568  }
569 
570  ff_blend_rectangle(&s->draw, &s->dark, out->data, out->linesize,
571  out->width, out->height,
572  X,
573  Y,
574  s->ww,
575  s->wh);
576 
577  for (y = 0; y < s->h; y++) {
578  for (x = 0; x < s->w; x++) {
579  FFDrawColor color = { { 0 } };
580  int value[4] = { 0 };
581 
582  s->pick_color(&s->draw, &color, in, x + s->x, y + s->y, value);
583  ff_fill_rectangle(&s->draw, &color, out->data, out->linesize,
584  x * w + (s->ww - 4 - (s->w * w)) / 2 + X, y * h + 2 + Y, w, h);
585  for (i = 0; i < 4; i++) {
586  rms[i] += (double)value[i] * (double)value[i];
587  average[i] += value[i];
588  min[i] = FFMIN(min[i], value[i]);
589  max[i] = FFMAX(max[i], value[i]);
590  }
591  }
592  }
593 
594  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
595  out->width, out->height,
596  s->x - 2, s->y - 2, s->w + 4, 1);
597 
598  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
599  out->width, out->height,
600  s->x - 1, s->y - 1, s->w + 2, 1);
601 
602  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
603  out->width, out->height,
604  s->x - 1, s->y - 1, 1, s->h + 2);
605 
606  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
607  out->width, out->height,
608  s->x - 2, s->y - 2, 1, s->h + 4);
609 
610  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
611  out->width, out->height,
612  s->x - 1, s->y + 1 + s->h, s->w + 3, 1);
613 
614  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
615  out->width, out->height,
616  s->x - 2, s->y + 2 + s->h, s->w + 4, 1);
617 
618  ff_blend_rectangle(&s->draw, &s->white, out->data, out->linesize,
619  out->width, out->height,
620  s->x + 1 + s->w, s->y - 1, 1, s->h + 2);
621 
622  ff_blend_rectangle(&s->draw, &s->black, out->data, out->linesize,
623  out->width, out->height,
624  s->x + 2 + s->w, s->y - 2, 1, s->h + 5);
625 
626  for (i = 0; i < 4; i++) {
627  rms[i] /= s->w * s->h;
628  rms[i] = sqrt(rms[i]);
629  average[i] /= s->w * s->h;
630  }
631 
632  snprintf(text, sizeof(text), "CH AVG MIN MAX RMS\n");
633  draw_text(&s->draw, out, &s->white, X + 28, Y + s->ww + 20, text, 0);
634  for (i = 0; i < s->nb_comps; i++) {
635  int c = s->rgba_map[i];
636 
637  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]);
638  draw_text(&s->draw, out, s->colors[i], X + 28, Y + s->ww + 20 * (i + 2), text, 0);
639  }
640 
641  av_frame_free(&in);
642  return ff_filter_frame(outlink, out);
643 }
644 
645 static const AVFilterPad pixscope_inputs[] = {
646  {
647  .name = "default",
648  .type = AVMEDIA_TYPE_VIDEO,
649  .filter_frame = pixscope_filter_frame,
650  .config_props = pixscope_config_input,
651  },
652  { NULL }
653 };
654 
655 static const AVFilterPad pixscope_outputs[] = {
656  {
657  .name = "default",
658  .type = AVMEDIA_TYPE_VIDEO,
659  },
660  { NULL }
661 };
662 
664  .name = "pixscope",
665  .description = NULL_IF_CONFIG_SMALL("Pixel data analysis."),
666  .priv_size = sizeof(PixscopeContext),
667  .priv_class = &pixscope_class,
672 };
673 
674 typedef struct PixelValues {
675  uint16_t p[4];
676 } PixelValues;
677 
678 typedef struct OscilloscopeContext {
679  const AVClass *class;
680 
681  float xpos, ypos;
682  float tx, ty;
683  float size;
684  float tilt;
685  float theight, twidth;
686  float o;
688  int grid;
690  int scope;
691 
692  int x1, y1, x2, y2;
693  int ox, oy;
694  int height, width;
695 
696  int max;
698  int nb_comps;
699  int is_rgb;
712 
715 
716  void (*pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value);
719 
720 #define OOFFSET(x) offsetof(OscilloscopeContext, x)
721 
722 static const AVOption oscilloscope_options[] = {
723  { "x", "set scope x position", OOFFSET(xpos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
724  { "y", "set scope y position", OOFFSET(ypos), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
725  { "s", "set scope size", OOFFSET(size), AV_OPT_TYPE_FLOAT, {.dbl=0.8}, 0, 1, FLAGS },
726  { "t", "set scope tilt", OOFFSET(tilt), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
727  { "o", "set trace opacity", OOFFSET(o), AV_OPT_TYPE_FLOAT, {.dbl=0.8}, 0, 1, FLAGS },
728  { "tx", "set trace x position", OOFFSET(tx), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
729  { "ty", "set trace y position", OOFFSET(ty), AV_OPT_TYPE_FLOAT, {.dbl=0.9}, 0, 1, FLAGS },
730  { "tw", "set trace width", OOFFSET(twidth), AV_OPT_TYPE_FLOAT, {.dbl=0.8},.1, 1, FLAGS },
731  { "th", "set trace height", OOFFSET(theight), AV_OPT_TYPE_FLOAT, {.dbl=0.3},.1, 1, FLAGS },
732  { "c", "set components to trace", OOFFSET(components), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, FLAGS },
733  { "g", "draw trace grid", OOFFSET(grid), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
734  { "st", "draw statistics", OOFFSET(statistics), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
735  { "sc", "draw scope", OOFFSET(scope), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
736  { NULL }
737 };
738 
739 AVFILTER_DEFINE_CLASS(oscilloscope);
740 
742 {
743  OscilloscopeContext *s = ctx->priv;
744 
745  av_freep(&s->values);
746 }
747 
748 static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1,
750 {
751  int dx = FFABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
752  int dy = FFABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
753  int err = (dx > dy ? dx : -dy) / 2, e2;
754  int p, i;
755 
756  for (;;) {
757  if (x0 >= 0 && y0 >= 0 && x0 < out->width && y0 < out->height) {
758  for (p = 0; p < draw->nb_planes; p++) {
759  if (draw->desc->comp[p].depth == 8) {
760  if (draw->nb_planes == 1) {
761  for (i = 0; i < 4; i++) {
762  out->data[0][y0 * out->linesize[0] + x0 * draw->pixelstep[0] + i] = color->comp[0].u8[i];
763  }
764  } else {
765  out->data[p][out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p])] = color->comp[p].u8[0];
766  }
767  } else {
768  if (draw->nb_planes == 1) {
769  for (i = 0; i < 4; i++) {
770  AV_WN16(out->data[0] + y0 * out->linesize[0] + 2 * (x0 * draw->pixelstep[0] + i), color->comp[0].u16[i]);
771  }
772  } else {
773  AV_WN16(out->data[p] + out->linesize[p] * (y0 >> draw->vsub[p]) + (x0 >> draw->hsub[p]) * 2, color->comp[p].u16[0]);
774  }
775  }
776  }
777  }
778 
779  if (x0 == x1 && y0 == y1)
780  break;
781 
782  e2 = err;
783 
784  if (e2 >-dx) {
785  err -= dy;
786  x0 += sx;
787  }
788 
789  if (e2 < dy) {
790  err += dx;
791  y0 += sy;
792  }
793  }
794 }
795 
797 {
798  int i, c;
799 
800  for (i = 1; i < s->nb_values; i++) {
801  for (c = 0; c < s->nb_comps; c++) {
802  if ((1 << c) & s->components) {
803  int x = i * s->width / s->nb_values;
804  int px = (i - 1) * s->width / s->nb_values;
805  int py = s->height - s->values[i-1].p[s->rgba_map[c]] * s->height / 256;
806  int y = s->height - s->values[i].p[s->rgba_map[c]] * s->height / 256;
807 
808  draw_line(&s->draw, s->ox + x, s->oy + y, s->ox + px, s->oy + py, frame, s->colors[c]);
809  }
810  }
811  }
812 }
813 
814 
816 {
817  int i, c;
818 
819  for (i = 1; i < s->nb_values; i++) {
820  for (c = 0; c < s->nb_comps; c++) {
821  if ((1 << c) & s->components) {
822  int x = i * s->width / s->nb_values;
823  int px = (i - 1) * s->width / s->nb_values;
824  int py = s->height - s->values[i-1].p[s->rgba_map[c]] * s->height / s->max;
825  int y = s->height - s->values[i].p[s->rgba_map[c]] * s->height / s->max;
826 
827  draw_line(&s->draw, s->ox + x, s->oy + y, s->ox + px, s->oy + py, frame, s->colors[c]);
828  }
829  }
830  }
831 }
832 
834 {
835  OscilloscopeContext *s = inlink->dst->priv;
836  int cx, cy, size;
837  double tilt;
838 
839  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
840  ff_draw_init(&s->draw, inlink->format, 0);
841  ff_draw_color(&s->draw, &s->dark, (uint8_t[]){ 0, 0, 0, s->o * 255} );
842  ff_draw_color(&s->draw, &s->black, (uint8_t[]){ 0, 0, 0, 255} );
843  ff_draw_color(&s->draw, &s->white, (uint8_t[]){ 255, 255, 255, 255} );
844  ff_draw_color(&s->draw, &s->green, (uint8_t[]){ 0, 255, 0, 255} );
845  ff_draw_color(&s->draw, &s->blue, (uint8_t[]){ 0, 0, 255, 255} );
846  ff_draw_color(&s->draw, &s->red, (uint8_t[]){ 255, 0, 0, 255} );
847  ff_draw_color(&s->draw, &s->cyan, (uint8_t[]){ 0, 255, 255, 255} );
848  ff_draw_color(&s->draw, &s->magenta, (uint8_t[]){ 255, 0, 255, 255} );
849  ff_draw_color(&s->draw, &s->gray, (uint8_t[]){ 128, 128, 128, 255} );
850  s->nb_comps = s->draw.desc->nb_components;
851  s->is_rgb = s->draw.desc->flags & AV_PIX_FMT_FLAG_RGB;
852 
853  if (s->is_rgb) {
854  s->colors[0] = &s->red;
855  s->colors[1] = &s->green;
856  s->colors[2] = &s->blue;
857  s->colors[3] = &s->white;
858  ff_fill_rgba_map(s->rgba_map, inlink->format);
859  } else {
860  s->colors[0] = &s->white;
861  s->colors[1] = &s->cyan;
862  s->colors[2] = &s->magenta;
863  s->colors[3] = &s->white;
864  s->rgba_map[0] = 0;
865  s->rgba_map[1] = 1;
866  s->rgba_map[2] = 2;
867  s->rgba_map[3] = 3;
868  }
869 
870  if (s->draw.desc->comp[0].depth <= 8) {
871  s->pick_color = pick_color8;
872  s->draw_trace = draw_trace8;
873  } else {
874  s->pick_color = pick_color16;
875  s->draw_trace = draw_trace16;
876  }
877 
878  s->max = (1 << s->draw.desc->comp[0].depth);
879  cx = s->xpos * (inlink->w - 1);
880  cy = s->ypos * (inlink->h - 1);
881  s->height = s->theight * inlink->h;
882  s->width = s->twidth * inlink->w;
883  size = hypot(inlink->w, inlink->h);
884 
885  s->values = av_calloc(size, sizeof(*s->values));
886  if (!s->values)
887  return AVERROR(ENOMEM);
888 
889  size *= s->size;
890  tilt = (s->tilt - 0.5) * M_PI;
891  s->x1 = cx - size / 2.0 * cos(tilt);
892  s->x2 = cx + size / 2.0 * cos(tilt);
893  s->y1 = cy - size / 2.0 * sin(tilt);
894  s->y2 = cy + size / 2.0 * sin(tilt);
895  s->ox = (inlink->w - s->width) * s->tx;
896  s->oy = (inlink->h - s->height) * s->ty;
897 
898  return 0;
899 }
900 
901 static void draw_scope(OscilloscopeContext *s, int x0, int y0, int x1, int y1,
902  AVFrame *out, PixelValues *p, int state)
903 {
904  int dx = FFABS(x1 - x0), sx = x0 < x1 ? 1 : -1;
905  int dy = FFABS(y1 - y0), sy = y0 < y1 ? 1 : -1;
906  int err = (dx > dy ? dx : -dy) / 2, e2;
907 
908  for (;;) {
909  if (x0 >= 0 && y0 >= 0 && x0 < out->width && y0 < out->height) {
910  FFDrawColor color = { { 0 } };
911  int value[4] = { 0 };
912 
913  s->pick_color(&s->draw, &color, out, x0, y0, value);
914  s->values[s->nb_values].p[0] = value[0];
915  s->values[s->nb_values].p[1] = value[1];
916  s->values[s->nb_values].p[2] = value[2];
917  s->values[s->nb_values].p[3] = value[3];
918  s->nb_values++;
919 
920  if (s->scope) {
921  if (s->draw.desc->comp[0].depth == 8) {
922  if (s->draw.nb_planes == 1) {
923  int i;
924 
925  for (i = 0; i < s->draw.pixelstep[0]; i++)
926  out->data[0][out->linesize[0] * y0 + x0 * s->draw.pixelstep[0] + i] = 255 * ((s->nb_values + state) & 1);
927  } else {
928  out->data[0][out->linesize[0] * y0 + x0] = 255 * ((s->nb_values + state) & 1);
929  }
930  } else {
931  if (s->draw.nb_planes == 1) {
932  int i;
933 
934  for (i = 0; i < s->draw.pixelstep[0]; i++)
935  AV_WN16(out->data[0] + out->linesize[0] * y0 + 2 * x0 * (s->draw.pixelstep[0] + i), (s->max - 1) * ((s->nb_values + state) & 1));
936  } else {
937  AV_WN16(out->data[0] + out->linesize[0] * y0 + 2 * x0, (s->max - 1) * ((s->nb_values + state) & 1));
938  }
939  }
940  }
941  }
942 
943  if (x0 == x1 && y0 == y1)
944  break;
945 
946  e2 = err;
947 
948  if (e2 >-dx) {
949  err -= dy;
950  x0 += sx;
951  }
952 
953  if (e2 < dy) {
954  err += dx;
955  y0 += sy;
956  }
957  }
958 }
959 
961 {
962  AVFilterContext *ctx = inlink->dst;
963  OscilloscopeContext *s = ctx->priv;
964  AVFilterLink *outlink = ctx->outputs[0];
965  float average[4] = { 0 };
966  int max[4] = { 0 };
967  int min[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
968  int i, c;
969 
970  s->nb_values = 0;
971  draw_scope(s, s->x1, s->y1, s->x2, s->y2, frame, s->values, inlink->frame_count_in & 1);
972  ff_blend_rectangle(&s->draw, &s->dark, frame->data, frame->linesize,
973  frame->width, frame->height,
974  s->ox, s->oy, s->width, s->height + 20 * s->statistics);
975 
976  if (s->grid) {
977  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
978  s->ox, s->oy, s->width - 1, 1);
979 
980  for (i = 1; i < 5; i++) {
981  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
982  s->ox, s->oy + i * (s->height - 1) / 4, s->width, 1);
983  }
984 
985  for (i = 0; i < 10; i++) {
986  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
987  s->ox + i * (s->width - 1) / 10, s->oy, 1, s->height);
988  }
989 
990  ff_fill_rectangle(&s->draw, &s->gray, frame->data, frame->linesize,
991  s->ox + s->width - 1, s->oy, 1, s->height);
992  }
993 
994  s->draw_trace(s, frame);
995 
996  for (i = 0; i < s->nb_values; i++) {
997  for (c = 0; c < s->nb_comps; c++) {
998  if ((1 << c) & s->components) {
999  max[c] = FFMAX(max[c], s->values[i].p[s->rgba_map[c]]);
1000  min[c] = FFMIN(min[c], s->values[i].p[s->rgba_map[c]]);
1001  average[c] += s->values[i].p[s->rgba_map[c]];
1002  }
1003  }
1004  }
1005  for (c = 0; c < s->nb_comps; c++) {
1006  average[c] /= s->nb_values;
1007  }
1008 
1009  if (s->statistics && s->height > 10 && s->width > 280 * av_popcount(s->components)) {
1010  for (c = 0, i = 0; c < s->nb_comps; c++) {
1011  if ((1 << c) & s->components) {
1012  const char rgba[4] = { 'R', 'G', 'B', 'A' };
1013  const char yuva[4] = { 'Y', 'U', 'V', 'A' };
1014  char text[128];
1015 
1016  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]);
1017  draw_text(&s->draw, frame, &s->white, s->ox + 2 + 280 * i++, s->oy + s->height + 4, text, 0);
1018  }
1019  }
1020  }
1021 
1022  return ff_filter_frame(outlink, frame);
1023 }
1024 
1026  {
1027  .name = "default",
1028  .type = AVMEDIA_TYPE_VIDEO,
1029  .filter_frame = oscilloscope_filter_frame,
1030  .config_props = oscilloscope_config_input,
1031  .needs_writable = 1,
1032  },
1033  { NULL }
1034 };
1035 
1037  {
1038  .name = "default",
1039  .type = AVMEDIA_TYPE_VIDEO,
1040  },
1041  { NULL }
1042 };
1043 
1045  .name = "oscilloscope",
1046  .description = NULL_IF_CONFIG_SMALL("2D Video Oscilloscope."),
1047  .priv_size = sizeof(OscilloscopeContext),
1048  .priv_class = &oscilloscope_class,
1054 };
OscilloscopeContext::o
float o
Definition: vf_datascope.c:686
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
ff_vf_datascope
AVFilter ff_vf_datascope
Definition: vf_datascope.c:412
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
PixscopeContext::colors
FFDrawColor * colors[4]
Definition: vf_datascope.c:445
td
#define td
Definition: regdef.h:70
FFDrawColor
Definition: drawutils.h:62
DatascopeContext::x
int x
Definition: vf_datascope.c:36
reverse_color8
static void reverse_color8(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:138
pixscope_inputs
static const AVFilterPad pixscope_inputs[]
Definition: vf_datascope.c:645
ff_vf_pixscope
AVFilter ff_vf_pixscope
Definition: vf_datascope.c:663
OscilloscopeContext::oy
int oy
Definition: vf_datascope.c:693
filter_mono
static int filter_mono(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:250
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:687
PixscopeContext::x
int x
Definition: vf_datascope.c:431
out
FILE * out
Definition: movenc.c:54
pixscope_outputs
static const AVFilterPad pixscope_outputs[]
Definition: vf_datascope.c:655
PixscopeContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_datascope.c:437
color
Definition: vf_paletteuse.c:588
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
filter_color2
static int filter_color2(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:170
OscilloscopeContext::theight
float theight
Definition: vf_datascope.c:685
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:202
DatascopeContext::gray
FFDrawColor gray
Definition: vf_datascope.c:48
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
PixscopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:438
pixdesc.h
FFDrawContext::desc
const struct AVPixFmtDescriptor * desc
Definition: drawutils.h:49
w
uint8_t w
Definition: llviddspenc.c:38
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:58
AVOption
AVOption.
Definition: opt.h:246
OscilloscopeContext::ox
int ox
Definition: vf_datascope.c:693
DatascopeContext::opacity
float opacity
Definition: vf_datascope.c:39
PixscopeContext::dark
FFDrawColor dark
Definition: vf_datascope.c:439
max
#define max(a, b)
Definition: cuda_runtime.h:33
PixscopeContext::y
int y
Definition: vf_datascope.c:431
OFFSET
#define OFFSET(x)
Definition: vf_datascope.c:55
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:148
FFDrawContext::nb_planes
unsigned nb_planes
Definition: drawutils.h:51
OOFFSET
#define OOFFSET(x)
Definition: vf_datascope.c:720
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:488
reverse
static uint32_t reverse(uint32_t num, int bits)
Definition: speedhq.c:565
pick_color8
static void pick_color8(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:102
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1795
OscilloscopeContext::max
int max
Definition: vf_datascope.c:696
FFDrawContext::pixelstep
int pixelstep[MAX_PLANES]
Definition: drawutils.h:52
formats.h
OscilloscopeContext::white
FFDrawColor white
Definition: vf_datascope.c:704
OscilloscopeContext::draw_trace
void(* draw_trace)(struct OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:717
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2562
OscilloscopeContext::gray
FFDrawColor gray
Definition: vf_datascope.c:710
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:353
ThreadData::yoff
int yoff
Definition: vf_datascope.c:167
DatascopeContext::chars
int chars
Definition: vf_datascope.c:43
OscilloscopeContext::y1
int y1
Definition: vf_datascope.c:692
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:622
PixscopeContext::is_rgb
int is_rgb
Definition: vf_datascope.c:436
PixscopeContext::blue
FFDrawColor blue
Definition: vf_datascope.c:443
DatascopeContext::reverse_color
void(* reverse_color)(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:51
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
C
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the C
Definition: writing_filters.txt:58
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
state
static struct @313 state
OscilloscopeContext::ty
float ty
Definition: vf_datascope.c:682
ff_set_common_formats
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:568
PixscopeContext::w
int w
Definition: vf_datascope.c:428
filter_color
static int filter_color(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:212
OscilloscopeContext::y2
int y2
Definition: vf_datascope.c:692
DatascopeContext::filter
int(* filter)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_datascope.c:52
OscilloscopeContext::ypos
float ypos
Definition: vf_datascope.c:681
width
#define width
W
#define W(a, i, v)
Definition: jpegls.h:124
intreadwrite.h
oscilloscope_uninit
static void oscilloscope_uninit(AVFilterContext *ctx)
Definition: vf_datascope.c:741
s
#define s(width, name)
Definition: cbs_vp9.c:257
PixelValues::p
uint16_t p[4]
Definition: vf_datascope.c:675
PixscopeContext::wy
float wy
Definition: vf_datascope.c:427
FFDrawContext::vsub
uint8_t vsub[MAX_PLANES]
Definition: drawutils.h:55
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:351
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2026
inputs
static const AVFilterPad inputs[]
Definition: vf_datascope.c:393
OscilloscopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:697
PixscopeContext::red
FFDrawColor red
Definition: vf_datascope.c:444
oscilloscope_outputs
static const AVFilterPad oscilloscope_outputs[]
Definition: vf_datascope.c:1036
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:90
OscilloscopeContext::height
int height
Definition: vf_datascope.c:694
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
Definition: drawutils.c:178
pick_color16
static void pick_color16(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:120
DatascopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:44
PixscopeContext::green
FFDrawColor green
Definition: vf_datascope.c:442
OscilloscopeContext::nb_values
int nb_values
Definition: vf_datascope.c:713
reverse_color16
static void reverse_color16(FFDrawContext *draw, FFDrawColor *color, FFDrawColor *reverse)
Definition: vf_datascope.c:150
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_datascope.c:74
arg
const char * arg
Definition: jacosubdec.c:66
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
POFFSET
#define POFFSET(x)
Definition: vf_datascope.c:450
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
PixscopeContext::white
FFDrawColor white
Definition: vf_datascope.c:441
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
H
F H1 F F H1 F F F F H1<-F-------F-------F v v v H2 H3 H2 ^ ^ ^ F-------F-------F-> H1<-F-------F-------F|||||||||F H1 F|||||||||F H1 Funavailable fullpel samples(outside the picture for example) shall be equalto the closest available fullpel sampleSmaller pel interpolation:--------------------------if diag_mc is set then points which lie on a line between 2 vertically, horizontally or diagonally adjacent halfpel points shall be interpolatedlinearly with rounding to nearest and halfway values rounded up.points which lie on 2 diagonals at the same time should only use the onediagonal not containing the fullpel point F--> O q O<--h1-> O q O<--F v \/v \/v O O O O O O O|/|\|q q q q q|/|\|O O O O O O O ^/\ ^/\ ^ h2--> O q O<--h3-> O q O<--h2 v \/v \/v O O O O O O O|\|/|q q q q q|\|/|O O O O O O O ^/\ ^/\ ^ F--> O q O<--h1-> O q O<--Fthe remaining points shall be bilinearly interpolated from theup to 4 surrounding halfpel and fullpel points, again rounding should be tonearest and halfway values rounded upcompliant Snow decoders MUST support 1-1/8 pel luma and 1/2-1/16 pel chromainterpolation at leastOverlapped block motion compensation:-------------------------------------FIXMELL band prediction:===================Each sample in the LL0 subband is predicted by the median of the left, top andleft+top-topleft samples, samples outside the subband shall be considered tobe 0. To reverse this prediction in the decoder apply the following.for(y=0;y< height;y++){ for(x=0;x< width;x++){ sample[y][x]+=median(sample[y-1][x], sample[y][x-1], sample[y-1][x]+sample[y][x-1]-sample[y-1][x-1]);}}sample[-1][ *]=sample[ *][-1]=0;width, height here are the width and height of the LL0 subband not of the finalvideoDequantization:===============FIXMEWavelet Transform:==================Snow supports 2 wavelet transforms, the symmetric biorthogonal 5/3 integertransform and an integer approximation of the symmetric biorthogonal 9/7daubechies wavelet.2D IDWT(inverse discrete wavelet transform) --------------------------------------------The 2D IDWT applies a 2D filter recursively, each time combining the4 lowest frequency subbands into a single subband until only 1 subbandremains.The 2D filter is done by first applying a 1D filter in the vertical directionand then applying it in the horizontal one. --------------- --------------- --------------- ---------------|LL0|HL0|||||||||||||---+---|HL1||L0|H0|HL1||LL1|HL1|||||LH0|HH0|||||||||||||-------+-------|-> L1 H1 LH1 HH1 LH1 HH1 LH1 HH1 this can end with a L or a H
Definition: snow.txt:555
OscilloscopeContext::magenta
FFDrawColor magenta
Definition: vf_datascope.c:709
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
Definition: opt.h:233
parseutils.h
DatascopeContext
Definition: vf_datascope.c:33
OscilloscopeContext::colors
FFDrawColor * colors[4]
Definition: vf_datascope.c:711
DatascopeContext::oh
int oh
Definition: vf_datascope.c:35
datascope_options
static const AVOption datascope_options[]
Definition: vf_datascope.c:58
oscilloscope_options
static const AVOption oscilloscope_options[]
Definition: vf_datascope.c:722
PixscopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:434
DatascopeContext::pick_color
void(* pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:50
OscilloscopeContext::tx
float tx
Definition: vf_datascope.c:682
draw_trace8
static void draw_trace8(OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:796
PixscopeContext::o
float o
Definition: vf_datascope.c:429
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(datascope)
OscilloscopeContext::red
FFDrawColor red
Definition: vf_datascope.c:707
draw_trace16
static void draw_trace16(OscilloscopeContext *s, AVFrame *frame)
Definition: vf_datascope.c:815
DatascopeContext::ow
int ow
Definition: vf_datascope.c:35
OscilloscopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:698
PixscopeContext::wh
int wh
Definition: vf_datascope.c:432
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:188
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_datascope.c:287
DatascopeContext::mode
int mode
Definition: vf_datascope.c:37
FLAGS
#define FLAGS
Definition: vf_datascope.c:56
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:148
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:445
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:792
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
outputs
static const AVFilterPad outputs[]
Definition: vf_datascope.c:403
size
int size
Definition: twinvq_data.h:11134
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
draw_text
static void draw_text(FFDrawContext *draw, AVFrame *frame, FFDrawColor *color, int x0, int y0, const uint8_t *text, int vertical)
Definition: vf_datascope.c:79
oscilloscope_inputs
static const AVFilterPad oscilloscope_inputs[]
Definition: vf_datascope.c:1025
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:318
OscilloscopeContext::cyan
FFDrawColor cyan
Definition: vf_datascope.c:708
pixscope_filter_frame
static int pixscope_filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_datascope.c:521
height
#define height
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
OscilloscopeContext::pick_color
void(* pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:716
OscilloscopeContext::size
float size
Definition: vf_datascope.c:683
ff_vf_oscilloscope
AVFilter ff_vf_oscilloscope
Definition: vf_datascope.c:1044
xga_font_data.h
OscilloscopeContext::x1
int x1
Definition: vf_datascope.c:692
DatascopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:42
M_PI
#define M_PI
Definition: mathematics.h:52
Y
#define Y
Definition: boxblur.h:38
internal.h
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:125
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:226
OscilloscopeContext::scope
int scope
Definition: vf_datascope.c:690
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
OscilloscopeContext
Definition: vf_datascope.c:678
OscilloscopeContext::black
FFDrawColor black
Definition: vf_datascope.c:703
PixscopeContext
Definition: vf_datascope.c:423
OscilloscopeContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_datascope.c:700
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
DatascopeContext::white
FFDrawColor white
Definition: vf_datascope.c:46
OscilloscopeContext::tilt
float tilt
Definition: vf_datascope.c:684
DatascopeContext::y
int y
Definition: vf_datascope.c:36
OscilloscopeContext::statistics
int statistics
Definition: vf_datascope.c:689
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:731
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
OscilloscopeContext::green
FFDrawColor green
Definition: vf_datascope.c:705
OscilloscopeContext::xpos
float xpos
Definition: vf_datascope.c:681
ThreadData
Used for passing data between threads.
Definition: af_adeclick.c:487
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
DatascopeContext::black
FFDrawColor black
Definition: vf_datascope.c:47
uint8_t
uint8_t
Definition: audio_convert.c:194
DatascopeContext::axis
int axis
Definition: vf_datascope.c:38
FFDrawContext
Definition: drawutils.h:48
OscilloscopeContext::dark
FFDrawColor dark
Definition: vf_datascope.c:702
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
OscilloscopeContext::is_rgb
int is_rgb
Definition: vf_datascope.c:699
DatascopeContext::nb_planes
int nb_planes
Definition: vf_datascope.c:41
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:231
AVFilter
Filter definition.
Definition: avfilter.h:144
PixscopeContext::pick_color
void(* pick_color)(FFDrawContext *draw, FFDrawColor *color, AVFrame *in, int x, int y, int *value)
Definition: vf_datascope.c:447
ThreadData::xoff
int xoff
Definition: vf_datascope.c:167
PixscopeContext::black
FFDrawColor black
Definition: vf_datascope.c:440
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
FFDrawContext::hsub
uint8_t hsub[MAX_PLANES]
Definition: drawutils.h:54
OscilloscopeContext::draw
FFDrawContext draw
Definition: vf_datascope.c:701
OscilloscopeContext::twidth
float twidth
Definition: vf_datascope.c:685
OscilloscopeContext::grid
int grid
Definition: vf_datascope.c:688
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
PixscopeContext::nb_comps
int nb_comps
Definition: vf_datascope.c:435
mode
mode
Definition: ebur128.h:83
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
PixscopeContext::xpos
float xpos
Definition: vf_datascope.c:426
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
PixscopeContext::ypos
float ypos
Definition: vf_datascope.c:426
AVFilterContext
An instance of a filter.
Definition: avfilter.h:338
PixscopeContext::h
int h
Definition: vf_datascope.c:428
OscilloscopeContext::width
int width
Definition: vf_datascope.c:694
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:116
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
ThreadData::in
AVFrame * in
Definition: af_afftdn.c:1082
PixscopeContext::wx
float wx
Definition: vf_datascope.c:427
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:901
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:382
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
draw_line
static void draw_line(FFDrawContext *draw, int x0, int y0, int x1, int y1, AVFrame *out, FFDrawColor *color)
Definition: vf_datascope.c:748
pixscope_options
static const AVOption pixscope_options[]
Definition: vf_datascope.c:452
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:465
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
DatascopeContext::yellow
FFDrawColor yellow
Definition: vf_datascope.c:45
OscilloscopeContext::blue
FFDrawColor blue
Definition: vf_datascope.c:706
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
h
h
Definition: vp9dsp_template.c:2038
OscilloscopeContext::values
PixelValues * values
Definition: vf_datascope.c:714
drawutils.h
OscilloscopeContext::x2
int x2
Definition: vf_datascope.c:692
int
int
Definition: ffmpeg_filter.c:191
PixelValues
Definition: vf_datascope.c:674
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
snprintf
#define snprintf
Definition: snprintf.h:34
oscilloscope_filter_frame
static int oscilloscope_filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: vf_datascope.c:960
PixscopeContext::ww
int ww
Definition: vf_datascope.c:432
oscilloscope_config_input
static int oscilloscope_config_input(AVFilterLink *inlink)
Definition: vf_datascope.c:833
min
float min
Definition: vorbis_enc_data.h:456
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:372